[evolution-data-server] Use GCancellable in all methods that may block.



commit db4fd695a3770cbaa817e9e294852697a5dc707d
Author: Matthew Barnes <mbarnes redhat com>
Date:   Sun May 9 11:26:48 2010 -0500

    Use GCancellable in all methods that may block.

 camel/camel-block-file.c                           |    2 +-
 camel/camel-cipher-context.c                       |  441 ++++----
 camel/camel-cipher-context.h                       |  113 ++-
 camel/camel-data-wrapper.c                         |   31 +-
 camel/camel-data-wrapper.h                         |    6 +
 camel/camel-disco-diary.c                          |   45 +-
 camel/camel-disco-diary.h                          |    1 +
 camel/camel-disco-folder.c                         |   73 +-
 camel/camel-disco-folder.h                         |   12 +
 camel/camel-disco-store.c                          |   62 +-
 camel/camel-disco-store.h                          |  126 ++-
 camel/camel-file-utils.c                           |  133 +--
 camel/camel-file-utils.h                           |   28 +-
 camel/camel-filter-driver.c                        |  126 ++-
 camel/camel-filter-driver.h                        |   33 +-
 camel/camel-filter-search.c                        |    4 +-
 camel/camel-folder-search.c                        |   36 +-
 camel/camel-folder-summary.c                       |    7 +-
 camel/camel-folder.c                               |  103 ++-
 camel/camel-folder.h                               |   24 +-
 camel/camel-gpg-context.c                          |  392 ++++----
 camel/camel-http-stream.c                          |   30 +-
 camel/camel-index-control.c                        |    2 +-
 camel/camel-lock-client.c                          |    2 +-
 camel/camel-mime-filter-progress.c                 |   41 +-
 camel/camel-mime-filter-progress.h                 |    3 +-
 camel/camel-mime-filter-save.c                     |    2 +-
 camel/camel-mime-message.c                         |   15 +-
 camel/camel-mime-parser.c                          |    2 +-
 camel/camel-mime-part-utils.c                      |   13 +-
 camel/camel-mime-part-utils.h                      |    1 +
 camel/camel-mime-part.c                            |  158 ++--
 camel/camel-mime-part.h                            |   89 +-
 camel/camel-mime-utils.c                           |    3 +-
 camel/camel-multipart-signed.c                     |   26 +-
 camel/camel-multipart.c                            |   11 +-
 camel/camel-net-utils.c                            |   42 +-
 camel/camel-net-utils.h                            |   20 +-
 camel/camel-offline-folder.c                       |   37 +-
 camel/camel-offline-folder.h                       |    2 +
 camel/camel-offline-journal.c                      |    5 +-
 camel/camel-offline-journal.h                      |   36 +-
 camel/camel-offline-store.c                        |   17 +-
 camel/camel-offline-store.h                        |   24 +-
 camel/camel-operation.c                            |  165 ++--
 camel/camel-operation.h                            |   18 +-
 camel/camel-sasl-anonymous.c                       |    1 +
 camel/camel-sasl-cram-md5.c                        |    1 +
 camel/camel-sasl-digest-md5.c                      |    6 +-
 camel/camel-sasl-gssapi.c                          |    6 +-
 camel/camel-sasl-login.c                           |    1 +
 camel/camel-sasl-ntlm.c                            |    1 +
 camel/camel-sasl-plain.c                           |    1 +
 camel/camel-sasl-popb4smtp.c                       |    1 +
 camel/camel-sasl.c                                 |   11 +-
 camel/camel-sasl.h                                 |    3 +
 camel/camel-search-private.c                       |    4 +-
 camel/camel-seekable-substream.c                   |   13 +-
 camel/camel-service.c                              |   47 +-
 camel/camel-service.h                              |    6 +-
 camel/camel-session.c                              |   22 +-
 camel/camel-session.h                              |    2 +-
 camel/camel-smime-context.c                        |   32 +-
 camel/camel-store.c                                |  102 ++-
 camel/camel-store.h                                |   24 +
 camel/camel-stream-buffer.c                        |   39 +-
 camel/camel-stream-buffer.h                        |    2 +
 camel/camel-stream-filter.c                        |   17 +-
 camel/camel-stream-fs.c                            |   12 +-
 camel/camel-stream-mem.c                           |    2 +
 camel/camel-stream-null.c                          |    1 +
 camel/camel-stream-process.c                       |   14 +-
 camel/camel-stream-vfs.c                           |   16 +-
 camel/camel-stream.c                               |   41 +-
 camel/camel-stream.h                               |   10 +
 camel/camel-tcp-stream-raw.c                       |  154 ++-
 camel/camel-tcp-stream-ssl.c                       |   15 +-
 camel/camel-tcp-stream.c                           |    9 +-
 camel/camel-tcp-stream.h                           |   10 +-
 camel/camel-transport.c                            |    5 +-
 camel/camel-transport.h                            |    2 +
 camel/camel-uid-cache.c                            |    6 +-
 camel/camel-vee-folder.c                           |   32 +-
 camel/camel-vee-folder.h                           |   24 +-
 camel/camel-vee-store.c                            |   10 +-
 camel/camel-vee-summary.c                          |   10 +-
 camel/camel-vtrash-folder.c                        |   24 +-
 camel/providers/groupwise/camel-groupwise-folder.c |  181 ++--
 camel/providers/groupwise/camel-groupwise-folder.h |   15 +-
 .../providers/groupwise/camel-groupwise-journal.c  |   65 +-
 .../providers/groupwise/camel-groupwise-journal.h  |   28 +-
 camel/providers/groupwise/camel-groupwise-store.c  |  152 ++-
 camel/providers/groupwise/camel-groupwise-store.h  |   38 +-
 .../providers/groupwise/camel-groupwise-summary.c  |   13 +-
 .../providers/groupwise/camel-groupwise-summary.h  |   24 +-
 .../groupwise/camel-groupwise-transport.c          |   10 +-
 camel/providers/groupwise/camel-groupwise-utils.c  |   19 +-
 camel/providers/imap/camel-imap-command.c          |   68 +-
 camel/providers/imap/camel-imap-command.h          |   63 +-
 camel/providers/imap/camel-imap-folder.c           |  410 +++++---
 camel/providers/imap/camel-imap-folder.h           |    7 +
 camel/providers/imap/camel-imap-journal.c          |   37 +-
 camel/providers/imap/camel-imap-journal.h          |   20 +-
 camel/providers/imap/camel-imap-message-cache.c    |   11 +-
 camel/providers/imap/camel-imap-message-cache.h    |    1 +
 camel/providers/imap/camel-imap-search.c           |   14 +-
 camel/providers/imap/camel-imap-store.c            | 1135 +++++++++++---------
 camel/providers/imap/camel-imap-store.h            |    2 +-
 camel/providers/imap/camel-imap-summary.c          |   16 +-
 camel/providers/imap/camel-imap-summary.h          |   23 +-
 camel/providers/imap/camel-imap-wrapper.c          |    7 +-
 camel/providers/imapx/camel-imapx-conn-manager.c   |   16 +-
 camel/providers/imapx/camel-imapx-conn-manager.h   |    1 +
 camel/providers/imapx/camel-imapx-folder.c         |   75 +-
 camel/providers/imapx/camel-imapx-server.c         |  720 ++++++++-----
 camel/providers/imapx/camel-imapx-server.h         |   17 +-
 camel/providers/imapx/camel-imapx-store.c          |  186 +++-
 camel/providers/imapx/camel-imapx-store.h          |    1 +
 camel/providers/imapx/camel-imapx-stream.c         |  141 ++-
 camel/providers/imapx/camel-imapx-stream.h         |   16 +-
 camel/providers/imapx/camel-imapx-utils.c          |  331 ++++---
 camel/providers/imapx/camel-imapx-utils.h          |   32 +-
 camel/providers/imapx/test-imapx.c                 |    8 +-
 camel/providers/local/camel-local-folder.c         |  472 +++++----
 camel/providers/local/camel-local-folder.h         |   13 +-
 camel/providers/local/camel-local-store.c          |   50 +-
 camel/providers/local/camel-local-summary.c        |   24 +-
 camel/providers/local/camel-local-summary.h        |    8 +-
 camel/providers/local/camel-maildir-folder.c       |  256 +++---
 camel/providers/local/camel-maildir-folder.h       |   10 +-
 camel/providers/local/camel-maildir-store.c        |   54 +-
 camel/providers/local/camel-maildir-summary.c      |   45 +-
 camel/providers/local/camel-mbox-folder.c          |  336 +++---
 camel/providers/local/camel-mbox-folder.h          |   11 +-
 camel/providers/local/camel-mbox-store.c           |   50 +-
 camel/providers/local/camel-mbox-summary.c         |  105 ++-
 camel/providers/local/camel-mbox-summary.h         |   32 +-
 camel/providers/local/camel-mh-folder.c            |  162 ++--
 camel/providers/local/camel-mh-folder.h            |   10 +-
 camel/providers/local/camel-mh-store.c             |   76 +-
 camel/providers/local/camel-mh-summary.c           |   15 +-
 camel/providers/local/camel-spool-folder.c         |  123 +--
 camel/providers/local/camel-spool-folder.h         |    9 +-
 camel/providers/local/camel-spool-store.c          |   45 +-
 camel/providers/local/camel-spool-summary.c        |   24 +-
 camel/providers/nntp/camel-nntp-folder.c           |   48 +-
 camel/providers/nntp/camel-nntp-folder.h           |   14 +-
 camel/providers/nntp/camel-nntp-store.c            |  406 +++++---
 camel/providers/nntp/camel-nntp-store.h            |    8 +-
 camel/providers/nntp/camel-nntp-stream.c           |   31 +-
 camel/providers/nntp/camel-nntp-stream.h           |    9 +-
 camel/providers/nntp/camel-nntp-summary.c          |   65 +-
 camel/providers/nntp/camel-nntp-summary.h          |   14 +-
 camel/providers/nntp/camel-nntp-types.h            |   37 -
 camel/providers/pop3/camel-pop3-engine.c           |    4 +-
 camel/providers/pop3/camel-pop3-folder.c           |  616 ++++++-----
 camel/providers/pop3/camel-pop3-folder.h           |   14 +-
 camel/providers/pop3/camel-pop3-store.c            |   55 +-
 camel/providers/pop3/camel-pop3-stream.c           |   22 +-
 .../providers/sendmail/camel-sendmail-transport.c  |   60 +-
 camel/providers/smtp/camel-smtp-transport.c        |  631 +++++++-----
 .../reference/camel/tmpl/camel-cipher-context.sgml |   21 +
 docs/reference/camel/tmpl/camel-data-wrapper.sgml  |    3 +
 docs/reference/camel/tmpl/camel-disco-diary.sgml   |    1 +
 docs/reference/camel/tmpl/camel-disco-folder.sgml  |    3 +
 docs/reference/camel/tmpl/camel-disco-store.sgml   |    2 +
 docs/reference/camel/tmpl/camel-file-utils.sgml    |    4 +
 docs/reference/camel/tmpl/camel-filter-driver.sgml |    3 +
 docs/reference/camel/tmpl/camel-folder.sgml        |    7 +
 .../camel/tmpl/camel-mime-filter-progress.sgml     |    2 +-
 docs/reference/camel/tmpl/camel-mime-part.sgml     |    2 +
 docs/reference/camel/tmpl/camel-net-utils.sgml     |    2 +
 .../reference/camel/tmpl/camel-offline-folder.sgml |    1 +
 .../camel/tmpl/camel-offline-journal.sgml          |    1 +
 docs/reference/camel/tmpl/camel-offline-store.sgml |    2 +
 docs/reference/camel/tmpl/camel-operation.sgml     |   34 +-
 docs/reference/camel/tmpl/camel-sasl.sgml          |    2 +
 docs/reference/camel/tmpl/camel-service.sgml       |    1 +
 docs/reference/camel/tmpl/camel-session.sgml       |    2 +-
 docs/reference/camel/tmpl/camel-store.sgml         |   12 +
 docs/reference/camel/tmpl/camel-stream-buffer.sgml |    2 +
 docs/reference/camel/tmpl/camel-stream.sgml        |    6 +
 docs/reference/camel/tmpl/camel-tcp-stream.sgml    |    1 +
 docs/reference/camel/tmpl/camel-transport.sgml     |    1 +
 docs/reference/camel/tmpl/camel-unused.sgml        |   23 +
 185 files changed, 6708 insertions(+), 4598 deletions(-)
---
diff --git a/camel/camel-block-file.c b/camel/camel-block-file.c
index a910e58..0b93d2a 100644
--- a/camel/camel-block-file.c
+++ b/camel/camel-block-file.c
@@ -573,7 +573,7 @@ camel_block_file_get_block (CamelBlockFile *bs,
 		bl = g_malloc0 (sizeof (*bl));
 		bl->id = id;
 		if (lseek (bs->fd, id, SEEK_SET) == -1 ||
-		    camel_read (bs->fd, (gchar *) bl->data, CAMEL_BLOCK_SIZE, NULL) == -1) {
+		    camel_read (bs->fd, (gchar *) bl->data, CAMEL_BLOCK_SIZE, NULL, NULL) == -1) {
 			block_file_unuse (bs);
 			CAMEL_BLOCK_FILE_UNLOCK (bs, cache_lock);
 			g_free (bl);
diff --git a/camel/camel-cipher-context.c b/camel/camel-cipher-context.c
index fd93f58..60d3bca 100644
--- a/camel/camel-cipher-context.c
+++ b/camel/camel-cipher-context.c
@@ -62,21 +62,220 @@ enum {
 
 G_DEFINE_TYPE (CamelCipherContext, camel_cipher_context, CAMEL_TYPE_OBJECT)
 
+static void
+cipher_context_set_session (CamelCipherContext *context,
+                            CamelSession *session)
+{
+	g_return_if_fail (CAMEL_IS_SESSION (session));
+	g_return_if_fail (context->priv->session == NULL);
+
+	context->priv->session = g_object_ref (session);
+}
+
+static void
+cipher_context_set_property (GObject *object,
+                             guint property_id,
+                             const GValue *value,
+                             GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_SESSION:
+			cipher_context_set_session (
+				CAMEL_CIPHER_CONTEXT (object),
+				g_value_get_object (value));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+cipher_context_get_property (GObject *object,
+                             guint property_id,
+                             GValue *value,
+                             GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_SESSION:
+			g_value_set_object (
+				value, camel_cipher_context_get_session (
+				CAMEL_CIPHER_CONTEXT (object)));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+cipher_context_dispose (GObject *object)
+{
+	CamelCipherContextPrivate *priv;
+
+	priv = CAMEL_CIPHER_CONTEXT_GET_PRIVATE (object);
+
+	if (priv->session != NULL) {
+		g_object_unref (priv->session);
+		priv->session = NULL;
+	}
+
+	/* Chain up to parent's dispose () method. */
+	G_OBJECT_CLASS (camel_cipher_context_parent_class)->dispose (object);
+}
+
+static void
+cipher_context_finalize (GObject *object)
+{
+	CamelCipherContextPrivate *priv;
+
+	priv = CAMEL_CIPHER_CONTEXT_GET_PRIVATE (object);
+
+	g_mutex_free (priv->lock);
+
+	/* Chain up to parent's finalize () method. */
+	G_OBJECT_CLASS (camel_cipher_context_parent_class)->finalize (object);
+}
+
+static const gchar *
+cipher_hash_to_id (CamelCipherContext *context,
+                   CamelCipherHash hash)
+{
+	return NULL;
+}
+
+static CamelCipherHash
+cipher_id_to_hash (CamelCipherContext *context,
+                   const gchar *id)
+{
+	return CAMEL_CIPHER_HASH_DEFAULT;
+}
+
 static gint
 cipher_sign (CamelCipherContext *ctx,
              const gchar *userid,
              CamelCipherHash hash,
              CamelMimePart *ipart,
              CamelMimePart *opart,
+             GCancellable *cancellable,
              GError **error)
 {
 	g_set_error (
-		error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
+		error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
 		_("Signing is not supported by this cipher"));
 
 	return -1;
 }
 
+static CamelCipherValidity *
+cipher_verify (CamelCipherContext *context,
+               CamelMimePart *sigpart,
+               GCancellable *cancellable,
+               GError **error)
+{
+	g_set_error (
+		error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+		_("Verifying is not supported by this cipher"));
+
+	return NULL;
+}
+
+static gint
+cipher_encrypt (CamelCipherContext *context,
+                const gchar *userid,
+                GPtrArray *recipients,
+                CamelMimePart *ipart,
+                CamelMimePart *opart,
+                GCancellable *cancellable,
+                GError **error)
+{
+	g_set_error (
+		error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+		_("Encryption is not supported by this cipher"));
+
+	return -1;
+}
+
+static CamelCipherValidity *
+cipher_decrypt (CamelCipherContext *context,
+                CamelMimePart *ipart,
+                CamelMimePart *opart,
+                GCancellable *cancellable,
+                GError **error)
+{
+	g_set_error (
+		error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+		_("Decryption is not supported by this cipher"));
+
+	return NULL;
+}
+
+static gint
+cipher_import_keys (CamelCipherContext *context,
+                    CamelStream *istream,
+                    GCancellable *cancellable,
+                    GError **error)
+{
+	g_set_error (
+		error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+		_("You may not import keys with this cipher"));
+
+	return -1;
+}
+
+static gint
+cipher_export_keys (CamelCipherContext *context,
+                    GPtrArray *keys,
+                    CamelStream *ostream,
+                    GCancellable *cancellable,
+                    GError **error)
+{
+	g_set_error (
+		error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+		_("You may not export keys with this cipher"));
+
+	return -1;
+}
+
+static void
+camel_cipher_context_class_init (CamelCipherContextClass *class)
+{
+	GObjectClass *object_class;
+
+	g_type_class_add_private (class, sizeof (CamelCipherContextPrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->set_property = cipher_context_set_property;
+	object_class->get_property = cipher_context_get_property;
+	object_class->dispose = cipher_context_dispose;
+	object_class->finalize = cipher_context_finalize;
+
+	class->hash_to_id = cipher_hash_to_id;
+	class->id_to_hash = cipher_id_to_hash;
+	class->sign = cipher_sign;
+	class->verify = cipher_verify;
+	class->encrypt = cipher_encrypt;
+	class->decrypt = cipher_decrypt;
+	class->import_keys = cipher_import_keys;
+	class->export_keys = cipher_export_keys;
+
+	g_object_class_install_property (
+		object_class,
+		PROP_SESSION,
+		g_param_spec_object (
+			"session",
+			"Session",
+			NULL,
+			CAMEL_TYPE_SESSION,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+camel_cipher_context_init (CamelCipherContext *context)
+{
+	context->priv = CAMEL_CIPHER_CONTEXT_GET_PRIVATE (context);
+	context->priv->lock = g_mutex_new ();
+}
+
 /**
  * camel_cipher_sign:
  * @context: Cipher Context
@@ -84,6 +283,7 @@ cipher_sign (CamelCipherContext *ctx,
  * @hash: preferred Message-Integrity-Check hash algorithm
  * @ipart: Input part.
  * @opart: output part.
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Converts the (unsigned) part @ipart into a new self-contained mime part @opart.
@@ -97,6 +297,7 @@ camel_cipher_sign (CamelCipherContext *context,
                    CamelCipherHash hash,
                    CamelMimePart *ipart,
                    CamelMimePart *opart,
+                   GCancellable *cancellable,
                    GError **error)
 {
 	CamelCipherContextClass *class;
@@ -107,36 +308,22 @@ camel_cipher_sign (CamelCipherContext *context,
 	class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
 	g_return_val_if_fail (class->sign != NULL, -1);
 
-	camel_operation_start (NULL, _("Signing message"));
-
 	CIPHER_LOCK (context);
 
-	retval = class->sign (context, userid, hash, ipart, opart, error);
+	retval = class->sign (
+		context, userid, hash, ipart, opart, cancellable, error);
 	CAMEL_CHECK_GERROR (context, sign, retval == 0, error);
 
 	CIPHER_UNLOCK (context);
 
-	camel_operation_end (NULL);
-
 	return retval;
 }
 
-static CamelCipherValidity *
-cipher_verify (CamelCipherContext *context,
-               CamelMimePart *sigpart,
-               GError **error)
-{
-	g_set_error (
-		error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
-		_("Verifying is not supported by this cipher"));
-
-	return NULL;
-}
-
 /**
  * camel_cipher_verify:
  * @context: Cipher Context
  * @ipart: part to verify
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Verifies the signature. If @istream is a clearsigned stream,
@@ -151,6 +338,7 @@ cipher_verify (CamelCipherContext *context,
 CamelCipherValidity *
 camel_cipher_verify (CamelCipherContext *context,
                      CamelMimePart *ipart,
+                     GCancellable *cancellable,
                      GError **error)
 {
 	CamelCipherContextClass *class;
@@ -161,35 +349,16 @@ camel_cipher_verify (CamelCipherContext *context,
 	class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
 	g_return_val_if_fail (class->verify != NULL, NULL);
 
-	camel_operation_start (NULL, _("Verifying message"));
-
 	CIPHER_LOCK (context);
 
-	valid = class->verify (context, ipart, error);
+	valid = class->verify (context, ipart, cancellable, error);
 	CAMEL_CHECK_GERROR (context, verify, valid != NULL, error);
 
 	CIPHER_UNLOCK (context);
 
-	camel_operation_end (NULL);
-
 	return valid;
 }
 
-static gint
-cipher_encrypt (CamelCipherContext *context,
-                const gchar *userid,
-                GPtrArray *recipients,
-                CamelMimePart *ipart,
-                CamelMimePart *opart,
-                GError **error)
-{
-	g_set_error (
-		error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
-		_("Encryption is not supported by this cipher"));
-
-	return -1;
-}
-
 /**
  * camel_cipher_encrypt:
  * @context: Cipher Context
@@ -197,6 +366,7 @@ cipher_encrypt (CamelCipherContext *context,
  * @recipients: an array of recipient key ids and/or email addresses
  * @ipart: cleartext input stream
  * @opart: ciphertext output stream
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Encrypts (and optionally signs) the cleartext input stream and
@@ -210,6 +380,7 @@ camel_cipher_encrypt (CamelCipherContext *context,
                       GPtrArray *recipients,
                       CamelMimePart *ipart,
                       CamelMimePart *opart,
+                      GCancellable *cancellable,
                       GError **error)
 {
 	CamelCipherContextClass *class;
@@ -220,39 +391,24 @@ camel_cipher_encrypt (CamelCipherContext *context,
 	class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
 	g_return_val_if_fail (class->encrypt != NULL, -1);
 
-	camel_operation_start (NULL, _("Encrypting message"));
-
 	CIPHER_LOCK (context);
 
 	retval = class->encrypt (
-		context, userid, recipients, ipart, opart, error);
+		context, userid, recipients,
+		ipart, opart, cancellable, error);
 	CAMEL_CHECK_GERROR (context, encrypt, retval == 0, error);
 
 	CIPHER_UNLOCK (context);
 
-	camel_operation_end (NULL);
-
 	return retval;
 }
 
-static CamelCipherValidity *
-cipher_decrypt (CamelCipherContext *context,
-                CamelMimePart *ipart,
-                CamelMimePart *opart,
-                GError **error)
-{
-	g_set_error (
-		error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
-		_("Decryption is not supported by this cipher"));
-
-	return NULL;
-}
-
 /**
  * camel_cipher_decrypt:
  * @context:
  * @ipart:
  * @opart:
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Decrypts @ipart into @opart.
@@ -263,6 +419,7 @@ CamelCipherValidity *
 camel_cipher_decrypt (CamelCipherContext *context,
                       CamelMimePart *ipart,
                       CamelMimePart *opart,
+                      GCancellable *cancellable,
                       GError **error)
 {
 	CamelCipherContextClass *class;
@@ -273,36 +430,21 @@ camel_cipher_decrypt (CamelCipherContext *context,
 	class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
 	g_return_val_if_fail (class->decrypt != NULL, NULL);
 
-	camel_operation_start (NULL, _("Decrypting message"));
-
 	CIPHER_LOCK (context);
 
-	valid = class->decrypt (context, ipart, opart, error);
+	valid = class->decrypt (context, ipart, opart, cancellable, error);
 	CAMEL_CHECK_GERROR (context, decrypt, valid != NULL, error);
 
 	CIPHER_UNLOCK (context);
 
-	camel_operation_end (NULL);
-
 	return valid;
 }
 
-static gint
-cipher_import_keys (CamelCipherContext *context,
-                    CamelStream *istream,
-                    GError **error)
-{
-	g_set_error (
-		error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
-		_("You may not import keys with this cipher"));
-
-	return -1;
-}
-
 /**
  * camel_cipher_import_keys:
  * @context: Cipher Context
  * @istream: input stream (containing keys)
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Imports a stream of keys/certificates contained within @istream
@@ -313,6 +455,7 @@ cipher_import_keys (CamelCipherContext *context,
 gint
 camel_cipher_import_keys (CamelCipherContext *context,
                           CamelStream *istream,
+                          GCancellable *cancellable,
                           GError **error)
 {
 	CamelCipherContextClass *class;
@@ -324,30 +467,18 @@ camel_cipher_import_keys (CamelCipherContext *context,
 	class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
 	g_return_val_if_fail (class->import_keys != NULL, -1);
 
-	retval = class->import_keys (context, istream, error);
+	retval = class->import_keys (context, istream, cancellable, error);
 	CAMEL_CHECK_GERROR (context, import_keys, retval == 0, error);
 
 	return retval;
 }
 
-static gint
-cipher_export_keys (CamelCipherContext *context,
-                    GPtrArray *keys,
-                    CamelStream *ostream,
-                    GError **error)
-{
-	g_set_error (
-		error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
-		_("You may not export keys with this cipher"));
-
-	return -1;
-}
-
 /**
  * camel_cipher_export_keys:
  * @context: Cipher Context
  * @keys: an array of key ids
  * @ostream: output stream
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Exports the keys/certificates in @keys to the stream @ostream from
@@ -359,6 +490,7 @@ gint
 camel_cipher_export_keys (CamelCipherContext *context,
                           GPtrArray *keys,
                           CamelStream *ostream,
+                          GCancellable *cancellable,
                           GError **error)
 {
 	CamelCipherContextClass *class;
@@ -371,18 +503,13 @@ camel_cipher_export_keys (CamelCipherContext *context,
 	class = CAMEL_CIPHER_CONTEXT_GET_CLASS (context);
 	g_return_val_if_fail (class->export_keys != NULL, -1);
 
-	retval = class->export_keys (context, keys, ostream, error);
+	retval = class->export_keys (
+		context, keys, ostream, cancellable, error);
 	CAMEL_CHECK_GERROR (context, export_keys, retval == 0, error);
 
 	return retval;
 }
 
-static CamelCipherHash
-cipher_id_to_hash (CamelCipherContext *context, const gchar *id)
-{
-	return CAMEL_CIPHER_HASH_DEFAULT;
-}
-
 /* a couple of util functions */
 CamelCipherHash
 camel_cipher_id_to_hash (CamelCipherContext *context,
@@ -401,12 +528,6 @@ camel_cipher_id_to_hash (CamelCipherContext *context,
 	return class->id_to_hash (context, id);
 }
 
-static const gchar *
-cipher_hash_to_id (CamelCipherContext *context, CamelCipherHash hash)
-{
-	return NULL;
-}
-
 const gchar *
 camel_cipher_hash_to_id (CamelCipherContext *context,
                          CamelCipherHash hash)
@@ -646,120 +767,6 @@ camel_cipher_validity_free (CamelCipherValidity *validity)
 
 /* ********************************************************************** */
 
-static void
-cipher_context_set_session (CamelCipherContext *context,
-                            CamelSession *session)
-{
-	g_return_if_fail (CAMEL_IS_SESSION (session));
-	g_return_if_fail (context->priv->session == NULL);
-
-	context->priv->session = g_object_ref (session);
-}
-
-static void
-cipher_context_set_property (GObject *object,
-                             guint property_id,
-                             const GValue *value,
-                             GParamSpec *pspec)
-{
-	switch (property_id) {
-		case PROP_SESSION:
-			cipher_context_set_session (
-				CAMEL_CIPHER_CONTEXT (object),
-				g_value_get_object (value));
-			return;
-	}
-
-	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-}
-
-static void
-cipher_context_get_property (GObject *object,
-                             guint property_id,
-                             GValue *value,
-                             GParamSpec *pspec)
-{
-	switch (property_id) {
-		case PROP_SESSION:
-			g_value_set_object (
-				value, camel_cipher_context_get_session (
-				CAMEL_CIPHER_CONTEXT (object)));
-			return;
-	}
-
-	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-}
-
-static void
-cipher_context_dispose (GObject *object)
-{
-	CamelCipherContextPrivate *priv;
-
-	priv = CAMEL_CIPHER_CONTEXT_GET_PRIVATE (object);
-
-	if (priv->session != NULL) {
-		g_object_unref (priv->session);
-		priv->session = NULL;
-	}
-
-	/* Chain up to parent's dispose () method. */
-	G_OBJECT_CLASS (camel_cipher_context_parent_class)->dispose (object);
-}
-
-static void
-cipher_context_finalize (GObject *object)
-{
-	CamelCipherContextPrivate *priv;
-
-	priv = CAMEL_CIPHER_CONTEXT_GET_PRIVATE (object);
-
-	g_mutex_free (priv->lock);
-
-	/* Chain up to parent's finalize () method. */
-	G_OBJECT_CLASS (camel_cipher_context_parent_class)->finalize (object);
-}
-
-static void
-camel_cipher_context_class_init (CamelCipherContextClass *class)
-{
-	GObjectClass *object_class;
-
-	g_type_class_add_private (class, sizeof (CamelCipherContextPrivate));
-
-	object_class = G_OBJECT_CLASS (class);
-	object_class->set_property = cipher_context_set_property;
-	object_class->get_property = cipher_context_get_property;
-	object_class->dispose = cipher_context_dispose;
-	object_class->finalize = cipher_context_finalize;
-
-	class->hash_to_id = cipher_hash_to_id;
-	class->id_to_hash = cipher_id_to_hash;
-	class->sign = cipher_sign;
-	class->verify = cipher_verify;
-	class->encrypt = cipher_encrypt;
-	class->decrypt = cipher_decrypt;
-	class->import_keys = cipher_import_keys;
-	class->export_keys = cipher_export_keys;
-
-	g_object_class_install_property (
-		object_class,
-		PROP_SESSION,
-		g_param_spec_object (
-			"session",
-			"Session",
-			NULL,
-			CAMEL_TYPE_SESSION,
-			G_PARAM_READWRITE |
-			G_PARAM_CONSTRUCT_ONLY));
-}
-
-static void
-camel_cipher_context_init (CamelCipherContext *context)
-{
-	context->priv = CAMEL_CIPHER_CONTEXT_GET_PRIVATE (context);
-	context->priv->lock = g_mutex_new ();
-}
-
 /**
  * camel_cipher_context_new:
  * @session: a #CamelSession
@@ -829,6 +836,7 @@ cc_prepare_sign (CamelMimePart *part)
  * @part: Part to write.
  * @flags: flags for the canonicalisation filter (CamelMimeFilterCanon)
  * @ostream: stream to write canonicalised output to.
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Writes a part to a stream in a canonicalised format, suitable for signing/encrypting.
@@ -841,6 +849,7 @@ gint
 camel_cipher_canonical_to_stream (CamelMimePart *part,
                                   guint32 flags,
                                   CamelStream *ostream,
+                                  GCancellable *cancellable,
                                   GError **error)
 {
 	CamelStream *filter;
@@ -856,8 +865,8 @@ camel_cipher_canonical_to_stream (CamelMimePart *part,
 	g_object_unref (canon);
 
 	if (camel_data_wrapper_write_to_stream (
-		(CamelDataWrapper *)part, filter, error) != -1
-	    && camel_stream_flush (filter, error) != -1)
+		CAMEL_DATA_WRAPPER (part), filter, cancellable, error) != -1
+	    && camel_stream_flush (filter, cancellable, error) != -1)
 		res = 0;
 
 	g_object_unref (filter);
diff --git a/camel/camel-cipher-context.h b/camel/camel-cipher-context.h
index 7b5a5d3..2e21efa 100644
--- a/camel/camel-cipher-context.h
+++ b/camel/camel-cipher-context.h
@@ -143,28 +143,34 @@ struct _CamelCipherContextClass {
 						 CamelCipherHash hash,
 						 CamelMimePart *ipart,
 						 CamelMimePart *opart,
+						 GCancellable *cancellable,
 						 GError **error);
 	CamelCipherValidity *
 			(*verify)		(CamelCipherContext *context,
 						 CamelMimePart *ipart,
+						 GCancellable *cancellable,
 						 GError **error);
 	gint		(*encrypt)		(CamelCipherContext *context,
 						 const gchar *userid,
 						 GPtrArray *recipients,
 						 CamelMimePart *ipart,
 						 CamelMimePart *opart,
+						 GCancellable *cancellable,
 						 GError **error);
 	CamelCipherValidity *
 			(*decrypt)		(CamelCipherContext *context,
 						 CamelMimePart *ipart,
 						 CamelMimePart *opart,
+						 GCancellable *cancellable,
 						 GError **error);
 	gint		(*import_keys)		(CamelCipherContext *context,
 						 CamelStream *istream,
+						 GCancellable *cancellable,
 						 GError **error);
 	gint		(*export_keys)		(CamelCipherContext *context,
 						 GPtrArray *keys,
 						 CamelStream *ostream,
+						 GCancellable *cancellable,
 						 GError **error);
 };
 
@@ -174,8 +180,10 @@ CamelCipherContext *
 CamelSession *	camel_cipher_context_get_session (CamelCipherContext *context);
 
 /* cipher context util routines */
-CamelCipherHash	     camel_cipher_id_to_hash (CamelCipherContext *context, const gchar *id);
-const gchar *	     camel_cipher_hash_to_id (CamelCipherContext *context, CamelCipherHash hash);
+CamelCipherHash	camel_cipher_id_to_hash		(CamelCipherContext *context,
+						 const gchar *id);
+const gchar *	camel_cipher_hash_to_id		(CamelCipherContext *context,
+						 CamelCipherHash hash);
 
 /* FIXME:
    There are some inconsistencies here, the api's should probably handle CamelMimePart's as input/outputs,
@@ -183,44 +191,81 @@ const gchar *	     camel_cipher_hash_to_id (CamelCipherContext *context, CamelCi
    to the cipher, etc etc. */
 
 /* cipher routines */
-gint                  camel_cipher_sign (CamelCipherContext *context, const gchar *userid, CamelCipherHash hash,
-					CamelMimePart *ipart, CamelMimePart *opart, GError **error);
-CamelCipherValidity *camel_cipher_verify (CamelCipherContext *context, CamelMimePart *ipart, GError **error);
-gint                  camel_cipher_encrypt (CamelCipherContext *context, const gchar *userid,
-					   GPtrArray *recipients, CamelMimePart *ipart, CamelMimePart *opart,
-					   GError **error);
-CamelCipherValidity *camel_cipher_decrypt (CamelCipherContext *context, CamelMimePart *ipart, CamelMimePart *opart,
-					   GError **error);
+gint		camel_cipher_sign		(CamelCipherContext *context,
+						 const gchar *userid,
+						 CamelCipherHash hash,
+						 CamelMimePart *ipart,
+						 CamelMimePart *opart,
+						 GCancellable *cancellable,
+						 GError **error);
+CamelCipherValidity *
+		camel_cipher_verify		(CamelCipherContext *context,
+						 CamelMimePart *ipart,
+						 GCancellable *cancellable,
+						 GError **error);
+gint		camel_cipher_encrypt		(CamelCipherContext *context,
+						 const gchar *userid,
+						 GPtrArray *recipients,
+						 CamelMimePart *ipart,
+						 CamelMimePart *opart,
+						 GCancellable *cancellable,
+						 GError **error);
+CamelCipherValidity *
+		camel_cipher_decrypt		(CamelCipherContext *context,
+						 CamelMimePart *ipart,
+						 CamelMimePart *opart,
+						 GCancellable *cancellable,
+						 GError **error);
 
 /* key/certificate routines */
-gint                  camel_cipher_import_keys (CamelCipherContext *context, CamelStream *istream,
-					       GError **error);
-gint                  camel_cipher_export_keys (CamelCipherContext *context, GPtrArray *keys,
-					       CamelStream *ostream, GError **error);
+gint		camel_cipher_import_keys	(CamelCipherContext *context,
+						 CamelStream *istream,
+						 GCancellable *cancellable,
+						 GError **error);
+gint		camel_cipher_export_keys	(CamelCipherContext *context,
+						 GPtrArray *keys,
+						 CamelStream *ostream,
+						 GCancellable *cancellable,
+						 GError **error);
 
 /* CamelCipherValidity utility functions */
-CamelCipherValidity *camel_cipher_validity_new (void);
-void                 camel_cipher_validity_init (CamelCipherValidity *validity);
-gboolean             camel_cipher_validity_get_valid (CamelCipherValidity *validity);
-void                 camel_cipher_validity_set_valid (CamelCipherValidity *validity, gboolean valid);
-gchar                *camel_cipher_validity_get_description (CamelCipherValidity *validity);
-void                 camel_cipher_validity_set_description (CamelCipherValidity *validity, const gchar *description);
-void                 camel_cipher_validity_clear (CamelCipherValidity *validity);
-CamelCipherValidity *camel_cipher_validity_clone (CamelCipherValidity *vin);
-void		     camel_cipher_validity_add_certinfo (CamelCipherValidity *vin, camel_cipher_validity_mode_t mode, const gchar *name, const gchar *email);
-void		     camel_cipher_validity_add_certinfo_ex (
-					CamelCipherValidity *vin,
-					camel_cipher_validity_mode_t mode,
-					const gchar *name,
-					const gchar *email,
-					gpointer cert_data,
-					void (*cert_data_free) (gpointer cert_data),
-					gpointer (*cert_data_clone) (gpointer cert_data));
-void		     camel_cipher_validity_envelope (CamelCipherValidity *parent, CamelCipherValidity *valid);
-void                 camel_cipher_validity_free (CamelCipherValidity *validity);
+CamelCipherValidity *
+		camel_cipher_validity_new	(void);
+void		camel_cipher_validity_init	(CamelCipherValidity *validity);
+gboolean	camel_cipher_validity_get_valid	(CamelCipherValidity *validity);
+void		camel_cipher_validity_set_valid	(CamelCipherValidity *validity,
+						 gboolean valid);
+gchar *		camel_cipher_validity_get_description
+						(CamelCipherValidity *validity);
+void		camel_cipher_validity_set_description
+						(CamelCipherValidity *validity,
+						 const gchar *description);
+void		camel_cipher_validity_clear	(CamelCipherValidity *validity);
+CamelCipherValidity *
+		camel_cipher_validity_clone	(CamelCipherValidity *vin);
+void		camel_cipher_validity_add_certinfo
+						(CamelCipherValidity *vin,
+						 camel_cipher_validity_mode_t mode,
+						 const gchar *name,
+						 const gchar *email);
+void		camel_cipher_validity_add_certinfo_ex (
+						CamelCipherValidity *vin,
+						camel_cipher_validity_mode_t mode,
+						const gchar *name,
+						const gchar *email,
+						gpointer cert_data,
+						void (*cert_data_free) (gpointer cert_data),
+						gpointer (*cert_data_clone) (gpointer cert_data));
+void		camel_cipher_validity_envelope	(CamelCipherValidity *parent,
+						 CamelCipherValidity *valid);
+void		camel_cipher_validity_free	(CamelCipherValidity *validity);
 
 /* utility functions */
-gint		     camel_cipher_canonical_to_stream (CamelMimePart *part, guint32 flags, CamelStream *ostream, GError **error);
+gint		camel_cipher_canonical_to_stream(CamelMimePart *part,
+						 guint32 flags,
+						 CamelStream *ostream,
+						 GCancellable *cancellable,
+						 GError **error);
 
 G_END_DECLS
 
diff --git a/camel/camel-data-wrapper.c b/camel/camel-data-wrapper.c
index 20bf199..d35eb49 100644
--- a/camel/camel-data-wrapper.c
+++ b/camel/camel-data-wrapper.c
@@ -79,6 +79,7 @@ data_wrapper_finalize (GObject *object)
 static gssize
 data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper,
                               CamelStream *stream,
+                              GCancellable *cancellable,
                               GError **error)
 {
 	gssize ret;
@@ -97,7 +98,7 @@ data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper,
 	}
 
 	ret = camel_stream_write_to_stream (
-		data_wrapper->stream, stream, error);
+		data_wrapper->stream, stream, cancellable, error);
 
 	camel_data_wrapper_unlock (data_wrapper, CAMEL_DATA_WRAPPER_STREAM_LOCK);
 
@@ -107,6 +108,7 @@ data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper,
 static gssize
 data_wrapper_decode_to_stream (CamelDataWrapper *data_wrapper,
                                CamelStream *stream,
+                               GCancellable *cancellable,
                                GError **error)
 {
 	CamelMimeFilter *filter;
@@ -142,9 +144,10 @@ data_wrapper_decode_to_stream (CamelDataWrapper *data_wrapper,
 		g_object_unref (filter);
 	}
 
-	ret = camel_data_wrapper_write_to_stream (data_wrapper, fstream, error);
+	ret = camel_data_wrapper_write_to_stream (
+		data_wrapper, fstream, cancellable, error);
 
-	camel_stream_flush (fstream, NULL);
+	camel_stream_flush (fstream, NULL, NULL);
 	g_object_unref (fstream);
 
 	return ret;
@@ -185,6 +188,7 @@ data_wrapper_set_mime_type_field (CamelDataWrapper *data_wrapper,
 static gint
 data_wrapper_construct_from_stream (CamelDataWrapper *data_wrapper,
                                     CamelStream *stream,
+                                    GCancellable *cancellable,
                                     GError **error)
 {
 	if (data_wrapper->stream)
@@ -252,6 +256,7 @@ camel_data_wrapper_new (void)
  * camel_data_wrapper_write_to_stream:
  * @data_wrapper: a #CamelDataWrapper object
  * @stream: a #CamelStream for output
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Writes the content of @data_wrapper to @stream in a machine-independent
@@ -264,6 +269,7 @@ camel_data_wrapper_new (void)
 gssize
 camel_data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper,
                                     CamelStream *stream,
+                                    GCancellable *cancellable,
                                     GError **error)
 {
 	CamelDataWrapperClass *class;
@@ -275,8 +281,10 @@ camel_data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper,
 	class = CAMEL_DATA_WRAPPER_GET_CLASS (data_wrapper);
 	g_return_val_if_fail (class->write_to_stream != NULL, -1);
 
-	n_bytes = class->write_to_stream (data_wrapper, stream, error);
-	CAMEL_CHECK_GERROR (data_wrapper, write_to_stream, n_bytes >= 0, error);
+	n_bytes = class->write_to_stream (
+		data_wrapper, stream, cancellable, error);
+	CAMEL_CHECK_GERROR (
+		data_wrapper, write_to_stream, n_bytes >= 0, error);
 
 	return n_bytes;
 }
@@ -285,6 +293,7 @@ camel_data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper,
  * camel_data_wrapper_decode_to_stream:
  * @data_wrapper: a #CamelDataWrapper object
  * @stream: a #CamelStream for decoded data to be written to
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Writes the decoded data content to @stream.
@@ -294,6 +303,7 @@ camel_data_wrapper_write_to_stream (CamelDataWrapper *data_wrapper,
 gssize
 camel_data_wrapper_decode_to_stream (CamelDataWrapper *data_wrapper,
                                      CamelStream *stream,
+                                     GCancellable *cancellable,
                                      GError **error)
 {
 	CamelDataWrapperClass *class;
@@ -305,8 +315,10 @@ camel_data_wrapper_decode_to_stream (CamelDataWrapper *data_wrapper,
 	class = CAMEL_DATA_WRAPPER_GET_CLASS (data_wrapper);
 	g_return_val_if_fail (class->decode_to_stream != NULL, -1);
 
-	n_bytes = class->decode_to_stream (data_wrapper, stream, error);
-	CAMEL_CHECK_GERROR (data_wrapper, decode_to_stream, n_bytes >= 0, error);
+	n_bytes = class->decode_to_stream (
+		data_wrapper, stream, cancellable, error);
+	CAMEL_CHECK_GERROR (
+		data_wrapper, decode_to_stream, n_bytes >= 0, error);
 
 	return n_bytes;
 }
@@ -315,6 +327,7 @@ camel_data_wrapper_decode_to_stream (CamelDataWrapper *data_wrapper,
  * camel_data_wrapper_construct_from_stream:
  * @data_wrapper: a #CamelDataWrapper object
  * @stream: an input #CamelStream
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Constructs the content of @data_wrapper from the supplied @stream.
@@ -324,6 +337,7 @@ camel_data_wrapper_decode_to_stream (CamelDataWrapper *data_wrapper,
 gint
 camel_data_wrapper_construct_from_stream (CamelDataWrapper *data_wrapper,
                                           CamelStream *stream,
+                                          GCancellable *cancellable,
                                           GError **error)
 {
 	CamelDataWrapperClass *class;
@@ -335,7 +349,8 @@ camel_data_wrapper_construct_from_stream (CamelDataWrapper *data_wrapper,
 	class = CAMEL_DATA_WRAPPER_GET_CLASS (data_wrapper);
 	g_return_val_if_fail (class->construct_from_stream != NULL, -1);
 
-	retval = class->construct_from_stream (data_wrapper, stream, error);
+	retval = class->construct_from_stream (
+		data_wrapper, stream, cancellable, error);
 	CAMEL_CHECK_GERROR (
 		data_wrapper, construct_from_stream, retval == 0, error);
 
diff --git a/camel/camel-data-wrapper.h b/camel/camel-data-wrapper.h
index cb41386..bbfbeea 100644
--- a/camel/camel-data-wrapper.h
+++ b/camel/camel-data-wrapper.h
@@ -92,12 +92,15 @@ struct _CamelDataWrapperClass {
 						 CamelContentType *mime_type_field);
 	gssize		(*write_to_stream)	(CamelDataWrapper *data_wrapper,
 						 CamelStream *stream,
+						 GCancellable *cancellable,
 						 GError **error);
 	gssize		(*decode_to_stream)	(CamelDataWrapper *data_wrapper,
 						 CamelStream *stream,
+						 GCancellable *cancellable,
 						 GError **error);
 	gint		(*construct_from_stream)(CamelDataWrapper *data_wrapper,
 						 CamelStream *stream,
+						 GCancellable *cancellable,
 						 GError **error);
 	gboolean	(*is_offline)		(CamelDataWrapper *data_wrapper);
 };
@@ -108,10 +111,12 @@ CamelDataWrapper *
 gssize		camel_data_wrapper_write_to_stream
 						(CamelDataWrapper *data_wrapper,
 						 CamelStream *stream,
+						 GCancellable *cancellable,
 						 GError **error);
 gssize		camel_data_wrapper_decode_to_stream
 						(CamelDataWrapper *data_wrapper,
 						 CamelStream *stream,
+						 GCancellable *cancellable,
 						 GError **error);
 void		camel_data_wrapper_set_mime_type (CamelDataWrapper *data_wrapper,
 						 const gchar *mime_type);
@@ -125,6 +130,7 @@ void		camel_data_wrapper_set_mime_type_field
 gint		camel_data_wrapper_construct_from_stream
 						(CamelDataWrapper *data_wrapper,
 						 CamelStream *stream,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_data_wrapper_is_offline	(CamelDataWrapper *data_wrapper);
 void		camel_data_wrapper_lock		(CamelDataWrapper *data_wrapper,
diff --git a/camel/camel-disco-diary.c b/camel/camel-disco-diary.c
index af87299..cddd2d9 100644
--- a/camel/camel-disco-diary.c
+++ b/camel/camel-disco-diary.c
@@ -237,7 +237,8 @@ diary_decode_uids (CamelDiscoDiary *diary)
 }
 
 static CamelFolder *
-diary_decode_folder (CamelDiscoDiary *diary)
+diary_decode_folder (CamelDiscoDiary *diary,
+                     GCancellable *cancellable)
 {
 	CamelFolder *folder;
 	gchar *name;
@@ -250,7 +251,8 @@ diary_decode_folder (CamelDiscoDiary *diary)
 		gchar *msg;
 
 		folder = camel_store_get_folder (
-			CAMEL_STORE (diary->store), name, 0, &error);
+			CAMEL_STORE (diary->store),
+			name, 0, cancellable, &error);
 		if (folder)
 			g_hash_table_insert (diary->folders, name, folder);
 		else {
@@ -273,20 +275,22 @@ diary_decode_folder (CamelDiscoDiary *diary)
 }
 
 static void
-close_folder (gpointer name, gpointer folder, gpointer data)
+close_folder (gchar *name,
+              CamelFolder *folder,
+              GCancellable *cancellable)
 {
 	g_free (name);
-	camel_folder_sync (folder, FALSE, NULL);
+	camel_folder_sync (folder, FALSE, cancellable, NULL);
 	g_object_unref (folder);
 }
 
 void
 camel_disco_diary_replay (CamelDiscoDiary *diary,
+                          GCancellable *cancellable,
                           GError **error)
 {
 	guint32 action;
 	goffset size;
-	gdouble pc;
 	GError *local_error = NULL;
 
 	d(printf("disco diary replay\n"));
@@ -296,10 +300,11 @@ camel_disco_diary_replay (CamelDiscoDiary *diary,
 	g_return_if_fail (size != 0);
 	rewind (diary->file);
 
-	camel_operation_start (NULL, _("Resynchronizing with server"));
+	camel_operation_start (cancellable, _("Resynchronizing with server"));
+
 	while (local_error == NULL) {
-		pc = ftell (diary->file) / size;
-		camel_operation_progress (NULL, pc * 100);
+		camel_operation_progress (
+			cancellable, (ftell (diary->file) / size) * 100);
 
 		if (camel_file_util_decode_uint32 (diary->file, &action) == -1)
 			break;
@@ -312,14 +317,15 @@ camel_disco_diary_replay (CamelDiscoDiary *diary,
 			CamelFolder *folder;
 			GPtrArray *uids;
 
-			folder = diary_decode_folder (diary);
+			folder = diary_decode_folder (diary, cancellable);
 			uids = diary_decode_uids (diary);
 			if (!uids)
 				goto lose;
 
 			if (folder)
 				camel_disco_folder_expunge_uids (
-					folder, uids, &local_error);
+					folder, uids, cancellable,
+					&local_error);
 			free_uids (uids);
 			break;
 		}
@@ -331,7 +337,7 @@ camel_disco_diary_replay (CamelDiscoDiary *diary,
 			CamelMimeMessage *message;
 			CamelMessageInfo *info;
 
-			folder = diary_decode_folder (diary);
+			folder = diary_decode_folder (diary, cancellable);
 			if (camel_file_util_decode_string (diary->file, &uid) == -1)
 				goto lose;
 
@@ -340,7 +346,8 @@ camel_disco_diary_replay (CamelDiscoDiary *diary,
 				continue;
 			}
 
-			message = camel_folder_get_message (folder, uid, NULL);
+			message = camel_folder_get_message (
+				folder, uid, cancellable, NULL);
 			if (!message) {
 				/* The message was appended and then deleted. */
 				g_free (uid);
@@ -349,7 +356,8 @@ camel_disco_diary_replay (CamelDiscoDiary *diary,
 			info = camel_folder_get_message_info (folder, uid);
 
 			camel_folder_append_message (
-				folder, message, info, &ret_uid, &local_error);
+				folder, message, info, &ret_uid,
+				cancellable, &local_error);
 			camel_folder_free_message_info (folder, info);
 
 			if (ret_uid) {
@@ -368,8 +376,8 @@ camel_disco_diary_replay (CamelDiscoDiary *diary,
 			guint32 delete_originals;
 			gint i;
 
-			source = diary_decode_folder (diary);
-			destination = diary_decode_folder (diary);
+			source = diary_decode_folder (diary, cancellable);
+			destination = diary_decode_folder (diary, cancellable);
 			uids = diary_decode_uids (diary);
 			if (!uids)
 				goto lose;
@@ -383,7 +391,7 @@ camel_disco_diary_replay (CamelDiscoDiary *diary,
 
 			camel_folder_transfer_messages_to (
 				source, uids, destination, &ret_uids,
-				delete_originals, &local_error);
+				delete_originals, cancellable, &local_error);
 
 			if (ret_uids) {
 				for (i = 0; i < uids->len; i++) {
@@ -402,10 +410,11 @@ camel_disco_diary_replay (CamelDiscoDiary *diary,
 	}
 
  lose:
-	camel_operation_end (NULL);
+	camel_operation_end (cancellable);
 
 	/* Close folders */
-	g_hash_table_foreach (diary->folders, close_folder, diary);
+	g_hash_table_foreach (
+		diary->folders, (GHFunc) close_folder, cancellable);
 	g_hash_table_destroy (diary->folders);
 	diary->folders = NULL;
 
diff --git a/camel/camel-disco-diary.h b/camel/camel-disco-diary.h
index 359600c..5c219cd 100644
--- a/camel/camel-disco-diary.h
+++ b/camel/camel-disco-diary.h
@@ -89,6 +89,7 @@ void		camel_disco_diary_log		(CamelDiscoDiary *diary,
 						 CamelDiscoDiaryAction action,
 						 ...);
 void		camel_disco_diary_replay	(CamelDiscoDiary *diary,
+						 GCancellable *cancellable,
 						 GError **error);
 
 /* Temporary->Permanent UID map stuff */
diff --git a/camel/camel-disco-folder.c b/camel/camel-disco-folder.c
index 12ed983..336d692 100644
--- a/camel/camel-disco-folder.c
+++ b/camel/camel-disco-folder.c
@@ -57,7 +57,9 @@ enum {
 G_DEFINE_TYPE (CamelDiscoFolder, camel_disco_folder, CAMEL_TYPE_FOLDER)
 
 /* Forward Declarations */
-static gboolean disco_expunge (CamelFolder *folder, GError **error);
+static gboolean		disco_expunge		(CamelFolder *folder,
+						 GCancellable *cancellable,
+						 GError **error);
 
 static void
 cdf_sync_offline (CamelSession *session, CamelSessionThreadMsg *mm)
@@ -65,24 +67,26 @@ cdf_sync_offline (CamelSession *session, CamelSessionThreadMsg *mm)
 	struct _cdf_sync_msg *m = (struct _cdf_sync_msg *)mm;
 	gint i;
 
-	camel_operation_start(NULL, _("Downloading new messages for offline mode"));
+	camel_operation_start (
+		mm->cancellable,
+		_("Downloading new messages for offline mode"));
 
 	if (m->changes) {
 		for (i=0;i<m->changes->uid_added->len;i++) {
 			gint pc = i * 100 / m->changes->uid_added->len;
 
-			camel_operation_progress (NULL, pc);
+			camel_operation_progress (mm->cancellable, pc);
 			camel_disco_folder_cache_message ((CamelDiscoFolder *)m->folder,
 							 m->changes->uid_added->pdata[i],
-							 &mm->error);
+							 NULL, &mm->error);
 		}
 	} else {
 		camel_disco_folder_prepare_for_offline ((CamelDiscoFolder *)m->folder,
 						       "(match-all)",
-						       &mm->error);
+						       NULL, &mm->error);
 	}
 
-	camel_operation_end (NULL);
+	camel_operation_end (mm->cancellable);
 }
 
 static void
@@ -161,6 +165,7 @@ disco_folder_get_property (GObject *object,
 
 static gboolean
 disco_refresh_info (CamelFolder *folder,
+                    GCancellable *cancellable,
                     GError **error)
 {
 	CamelDiscoFolderClass *disco_folder_class;
@@ -174,7 +179,8 @@ disco_refresh_info (CamelFolder *folder,
 
 	disco_folder_class = CAMEL_DISCO_FOLDER_GET_CLASS (folder);
 
-	success = disco_folder_class->refresh_info_online (folder, error);
+	success = disco_folder_class->refresh_info_online (
+		folder, cancellable, error);
 	CAMEL_CHECK_GERROR (folder, refresh_info_online, success, error);
 
 	return success;
@@ -183,13 +189,14 @@ disco_refresh_info (CamelFolder *folder,
 static gboolean
 disco_sync (CamelFolder *folder,
             gboolean expunge,
+            GCancellable *cancellable,
             GError **error)
 {
 	CamelDiscoFolderClass *disco_folder_class;
 	CamelStore *parent_store;
 	gboolean success;
 
-	if (expunge && !disco_expunge (folder, error))
+	if (expunge && !disco_expunge (folder, cancellable, error))
 		return FALSE;
 
 	camel_object_state_write (CAMEL_OBJECT (folder));
@@ -220,6 +227,7 @@ disco_sync (CamelFolder *folder,
 static gboolean
 disco_expunge_uids (CamelFolder *folder,
                     GPtrArray *uids,
+                    GCancellable *cancellable,
                     GError **error)
 {
 	CamelDiscoFolderClass *disco_folder_class;
@@ -260,6 +268,7 @@ disco_expunge_uids (CamelFolder *folder,
 
 static gboolean
 disco_expunge (CamelFolder *folder,
+               GCancellable *cancellable,
                GError **error)
 {
 	GPtrArray *uids;
@@ -278,7 +287,7 @@ disco_expunge (CamelFolder *folder,
 		camel_message_info_free (info);
 	}
 
-	success = disco_expunge_uids (folder, uids, error);
+	success = disco_expunge_uids (folder, uids, cancellable, error);
 
 	for (i = 0; i < uids->len; i++)
 		g_free (uids->pdata[i]);
@@ -292,6 +301,7 @@ disco_append_message (CamelFolder *folder,
                       CamelMimeMessage *message,
                       const CamelMessageInfo *info,
                       gchar **appended_uid,
+                      GCancellable *cancellable,
                       GError **error)
 {
 	CamelDiscoFolderClass *disco_folder_class;
@@ -304,19 +314,22 @@ disco_append_message (CamelFolder *folder,
 	switch (camel_disco_store_status (CAMEL_DISCO_STORE (parent_store))) {
 	case CAMEL_DISCO_STORE_ONLINE:
 		success = disco_folder_class->append_online (
-			folder, message, info, appended_uid, error);
+			folder, message, info,
+			appended_uid, cancellable, error);
 		CAMEL_CHECK_GERROR (folder, append_online, success, error);
 		return success;
 
 	case CAMEL_DISCO_STORE_OFFLINE:
 		success = disco_folder_class->append_offline (
-			folder, message, info, appended_uid, error);
+			folder, message, info,
+			appended_uid, cancellable, error);
 		CAMEL_CHECK_GERROR (folder, append_offline, success, error);
 		return success;
 
 	case CAMEL_DISCO_STORE_RESYNCING:
 		success = disco_folder_class->append_resyncing (
-			folder, message, info, appended_uid, error);
+			folder, message, info,
+			appended_uid, cancellable, error);
 		CAMEL_CHECK_GERROR (folder, append_resyncing, success, error);
 		return success;
 	}
@@ -330,6 +343,7 @@ disco_transfer_messages_to (CamelFolder *source,
                             CamelFolder *dest,
                             GPtrArray **transferred_uids,
                             gboolean delete_originals,
+                            GCancellable *cancellable,
                             GError **error)
 {
 	CamelDiscoFolderClass *disco_folder_class;
@@ -343,21 +357,21 @@ disco_transfer_messages_to (CamelFolder *source,
 	case CAMEL_DISCO_STORE_ONLINE:
 		success = disco_folder_class->transfer_online (
 			source, uids, dest, transferred_uids,
-			delete_originals, error);
+			delete_originals, cancellable, error);
 		CAMEL_CHECK_GERROR (source, transfer_online, success, error);
 		return success;
 
 	case CAMEL_DISCO_STORE_OFFLINE:
 		success = disco_folder_class->transfer_offline (
 			source, uids, dest, transferred_uids,
-			delete_originals, error);
+			delete_originals, cancellable, error);
 		CAMEL_CHECK_GERROR (source, transfer_offline, success, error);
 		return success;
 
 	case CAMEL_DISCO_STORE_RESYNCING:
 		success = disco_folder_class->transfer_resyncing (
 			source, uids, dest, transferred_uids,
-			delete_originals, error);
+			delete_originals, cancellable, error);
 		CAMEL_CHECK_GERROR (source, transfer_resyncing, success, error);
 		return success;
 	}
@@ -368,6 +382,7 @@ disco_transfer_messages_to (CamelFolder *source,
 static gboolean
 disco_prepare_for_offline (CamelDiscoFolder *disco_folder,
                            const gchar *expression,
+                           GCancellable *cancellable,
                            GError **error)
 {
 	CamelFolder *folder = CAMEL_FOLDER (disco_folder);
@@ -376,7 +391,7 @@ disco_prepare_for_offline (CamelDiscoFolder *disco_folder,
 	gboolean success = TRUE;
 
 	camel_operation_start (
-		NULL, _("Preparing folder '%s' for offline"),
+		cancellable, _("Preparing folder '%s' for offline"),
 		camel_folder_get_full_name (folder));
 
 	if (expression)
@@ -385,16 +400,15 @@ disco_prepare_for_offline (CamelDiscoFolder *disco_folder,
 		uids = camel_folder_get_uids (folder);
 
 	if (!uids) {
-		camel_operation_end (NULL);
+		camel_operation_end (cancellable);
 		return FALSE;
 	}
 
 	for (i = 0; i < uids->len && success; i++) {
-		gint pc = i * 100 / uids->len;
-
-		camel_operation_progress (NULL, pc);
+		camel_operation_progress (
+			cancellable, (i * 100) / uids->len);
 		success = camel_disco_folder_cache_message (
-			disco_folder, uids->pdata[i], error);
+			disco_folder, uids->pdata[i], cancellable, error);
 	}
 
 	if (expression)
@@ -402,13 +416,14 @@ disco_prepare_for_offline (CamelDiscoFolder *disco_folder,
 	else
 		camel_folder_free_uids (folder, uids);
 
-	camel_operation_end (NULL);
+	camel_operation_end (cancellable);
 
 	return success;
 }
 
 static gboolean
 disco_refresh_info_online (CamelFolder *folder,
+                           GCancellable *cancellable,
                            GError **error)
 {
 	return TRUE;
@@ -494,6 +509,7 @@ camel_disco_folder_set_offline_sync (CamelDiscoFolder *disco_folder,
  * camel_disco_folder_expunge_uids:
  * @folder: a (disconnectable) folder
  * @uids: array of UIDs to expunge
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * This expunges the messages in @uids from @folder. It should take
@@ -507,18 +523,20 @@ camel_disco_folder_set_offline_sync (CamelDiscoFolder *disco_folder,
 gboolean
 camel_disco_folder_expunge_uids (CamelFolder *folder,
                                  GPtrArray *uids,
+                                 GCancellable *cancellable,
                                  GError **error)
 {
 	g_return_val_if_fail (CAMEL_IS_DISCO_FOLDER (folder), FALSE);
 	g_return_val_if_fail (uids != NULL, FALSE);
 
-	return disco_expunge_uids (folder, uids, error);
+	return disco_expunge_uids (folder, uids, cancellable, error);
 }
 
 /**
  * camel_disco_folder_cache_message:
  * @disco_folder: the folder
  * @uid: the UID of the message to cache
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Requests that @disco_folder cache message @uid to disk.
@@ -528,6 +546,7 @@ camel_disco_folder_expunge_uids (CamelFolder *folder,
 gboolean
 camel_disco_folder_cache_message (CamelDiscoFolder *disco_folder,
                                   const gchar *uid,
+                                  GCancellable *cancellable,
                                   GError **error)
 {
 	CamelDiscoFolderClass *class;
@@ -539,7 +558,8 @@ camel_disco_folder_cache_message (CamelDiscoFolder *disco_folder,
 	class = CAMEL_DISCO_FOLDER_GET_CLASS (disco_folder);
 	g_return_val_if_fail (class->cache_message != NULL, FALSE);
 
-	success = class->cache_message (disco_folder, uid, error);
+	success = class->cache_message (
+		disco_folder, uid, cancellable, error);
 	CAMEL_CHECK_GERROR (disco_folder, cache_message, success, error);
 
 	return success;
@@ -550,6 +570,7 @@ camel_disco_folder_cache_message (CamelDiscoFolder *disco_folder,
  * @disco_folder: the folder
  * @expression: an expression describing messages to synchronize, or %NULL
  * if all messages should be sync'ed.
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * This prepares @disco_folder for offline operation, by downloading
@@ -561,6 +582,7 @@ camel_disco_folder_cache_message (CamelDiscoFolder *disco_folder,
 gboolean
 camel_disco_folder_prepare_for_offline (CamelDiscoFolder *disco_folder,
                                         const gchar *expression,
+                                        GCancellable *cancellable,
                                         GError **error)
 {
 	CamelDiscoFolderClass *class;
@@ -571,7 +593,8 @@ camel_disco_folder_prepare_for_offline (CamelDiscoFolder *disco_folder,
 	class = CAMEL_DISCO_FOLDER_GET_CLASS (disco_folder);
 	g_return_val_if_fail (class->prepare_for_offline != NULL, FALSE);
 
-	success = class->prepare_for_offline (disco_folder, expression, error);
+	success = class->prepare_for_offline (
+		disco_folder, expression, cancellable, error);
 	CAMEL_CHECK_GERROR (disco_folder, prepare_for_offline, success, error);
 
 	return success;
diff --git a/camel/camel-disco-folder.h b/camel/camel-disco-folder.h
index 7df9fe7..f90ae49 100644
--- a/camel/camel-disco-folder.h
+++ b/camel/camel-disco-folder.h
@@ -66,6 +66,7 @@ struct _CamelDiscoFolderClass {
 	CamelFolderClass parent_class;
 
 	gboolean	(*refresh_info_online)	(CamelFolder *folder,
+						 GCancellable *cancellable,
 						 GError **error);
 	gboolean	(*sync_online)		(CamelFolder *folder,
 						 GError **error);
@@ -87,40 +88,48 @@ struct _CamelDiscoFolderClass {
 						 CamelMimeMessage *message,
 						 const CamelMessageInfo *info,
 						 gchar **appended_uid,
+						 GCancellable *cancellable,
 						 GError **error);
 	gboolean	(*append_offline)	(CamelFolder *folder,
 						 CamelMimeMessage *message,
 						 const CamelMessageInfo *info,
 						 gchar **appended_uid,
+						 GCancellable *cancellable,
 						 GError **error);
 	gboolean	(*append_resyncing)	(CamelFolder *folder,
 						 CamelMimeMessage *message,
 						 const CamelMessageInfo *info,
 						 gchar **appended_uid,
+						 GCancellable *cancellable,
 						 GError **error);
 	gboolean	(*transfer_online)	(CamelFolder *source,
 						 GPtrArray *uids,
 						 CamelFolder *destination,
 						 GPtrArray **transferred_uids,
 						 gboolean delete_originals,
+						 GCancellable *cancellable,
 						 GError **error);
 	gboolean	(*transfer_offline)	(CamelFolder *source,
 						 GPtrArray *uids,
 						 CamelFolder *destination,
 						 GPtrArray **transferred_uids,
 						 gboolean delete_originals,
+						 GCancellable *cancellable,
 						 GError **error);
 	gboolean	(*transfer_resyncing)	(CamelFolder *source,
 						 GPtrArray *uids,
 						 CamelFolder *destination,
 						 GPtrArray **transferred_uids,
 						 gboolean delete_originals,
+						 GCancellable *cancellable,
 						 GError **error);
 	gboolean	(*cache_message)	(CamelDiscoFolder *disco_folder,
 						 const gchar *uid,
+						 GCancellable *cancellable,
 						 GError **error);
 	gboolean	(*prepare_for_offline)	(CamelDiscoFolder *disco_folder,
 						 const gchar *expression,
+						 GCancellable *cancellable,
 						 GError **error);
 	void		(*update_uid)		(CamelFolder *folder,
 						 const gchar *old_uid,
@@ -135,13 +144,16 @@ void		camel_disco_folder_set_offline_sync
 						 gboolean offline_sync);
 gboolean	camel_disco_folder_expunge_uids	(CamelFolder *folder,
 						 GPtrArray *uids,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_disco_folder_cache_message (CamelDiscoFolder *disco_folder,
 						 const gchar *uid,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_disco_folder_prepare_for_offline
 						(CamelDiscoFolder *disco_folder,
 						 const gchar *expression,
+						 GCancellable *cancellable,
 						 GError **error);
 
 G_END_DECLS
diff --git a/camel/camel-disco-store.c b/camel/camel-disco-store.c
index b35c4b4..92fa78c 100644
--- a/camel/camel-disco-store.c
+++ b/camel/camel-disco-store.c
@@ -61,6 +61,7 @@ disco_store_construct (CamelService *service,
 
 static gboolean
 disco_store_connect (CamelService *service,
+                     GCancellable *cancellable,
                      GError **error)
 {
 	CamelDiscoStore *store = CAMEL_DISCO_STORE (service);
@@ -70,7 +71,7 @@ disco_store_connect (CamelService *service,
 
 	status = camel_disco_store_status (store);
 	if (status != CAMEL_DISCO_STORE_OFFLINE) {
-		if (!CAMEL_SERVICE_CLASS (camel_disco_store_parent_class)->connect (service, error)) {
+		if (!CAMEL_SERVICE_CLASS (camel_disco_store_parent_class)->connect (service, cancellable, error)) {
 			status = camel_disco_store_status (store);
 			if (status != CAMEL_DISCO_STORE_OFFLINE)
 				return FALSE;
@@ -81,7 +82,7 @@ disco_store_connect (CamelService *service,
 	switch (status) {
 	case CAMEL_DISCO_STORE_ONLINE:
 	case CAMEL_DISCO_STORE_RESYNCING:
-		if (!CAMEL_DISCO_STORE_GET_CLASS (service)->connect_online (service, error))
+		if (!CAMEL_DISCO_STORE_GET_CLASS (service)->connect_online (service, cancellable, error))
 			return FALSE;
 
 		if (!store->diary)
@@ -95,7 +96,7 @@ disco_store_connect (CamelService *service,
 		   disconnect could be called, which will remove store->diary and unref it */
 		store->status = CAMEL_DISCO_STORE_RESYNCING;
 		diary = g_object_ref (store->diary);
-		camel_disco_diary_replay (diary, &local_error);
+		camel_disco_diary_replay (diary, cancellable, &local_error);
 		g_object_unref (diary);
 		store->status = CAMEL_DISCO_STORE_ONLINE;
 		if (local_error != NULL) {
@@ -108,7 +109,7 @@ disco_store_connect (CamelService *service,
 		return camel_service_connect (service, error);
 
 	case CAMEL_DISCO_STORE_OFFLINE:
-		return CAMEL_DISCO_STORE_GET_CLASS (service)->connect_offline (service, error);
+		return CAMEL_DISCO_STORE_GET_CLASS (service)->connect_offline (service, cancellable, error);
 	}
 
 	g_assert_not_reached ();
@@ -118,25 +119,32 @@ disco_store_connect (CamelService *service,
 static gboolean
 disco_store_disconnect (CamelService *service,
                         gboolean clean,
+                        GCancellable *cancellable,
                         GError **error)
 {
 	CamelDiscoStore *store = CAMEL_DISCO_STORE (service);
+	CamelDiscoStoreClass *class;
+
+	class = CAMEL_DISCO_STORE_GET_CLASS (service);
 
 	switch (camel_disco_store_status (store)) {
 	case CAMEL_DISCO_STORE_ONLINE:
 	case CAMEL_DISCO_STORE_RESYNCING:
-		if (!CAMEL_DISCO_STORE_GET_CLASS (service)->disconnect_online (service, clean, error))
+		if (!class->disconnect_online (
+			service, clean, cancellable, error))
 			return FALSE;
 		break;
 
 	case CAMEL_DISCO_STORE_OFFLINE:
-		if (!CAMEL_DISCO_STORE_GET_CLASS (service)->disconnect_offline (service, clean, error))
+		if (!class->disconnect_offline (
+			service, clean, cancellable, error))
 			return FALSE;
 		break;
 
 	}
 
-	return CAMEL_SERVICE_CLASS (camel_disco_store_parent_class)->disconnect (service, clean, error);
+	return CAMEL_SERVICE_CLASS (camel_disco_store_parent_class)->
+		disconnect (service, clean, cancellable, error);
 }
 
 static void
@@ -153,6 +161,7 @@ static CamelFolder *
 disco_store_get_folder (CamelStore *store,
                         const gchar *name,
                         guint32 flags,
+                        GCancellable *cancellable,
                         GError **error)
 {
 	CamelDiscoStore *disco_store = CAMEL_DISCO_STORE (store);
@@ -166,17 +175,20 @@ disco_store_get_folder (CamelStore *store,
 
 	switch (camel_disco_store_status (disco_store)) {
 	case CAMEL_DISCO_STORE_ONLINE:
-		folder = class->get_folder_online (store, name, flags, error);
+		folder = class->get_folder_online (
+			store, name, flags, cancellable, error);
 		CAMEL_CHECK_GERROR (store, get_folder_online, folder != NULL, error);
 		return folder;
 
 	case CAMEL_DISCO_STORE_OFFLINE:
-		folder = class->get_folder_offline (store, name, flags, error);
+		folder = class->get_folder_offline (
+			store, name, flags, cancellable, error);
 		CAMEL_CHECK_GERROR (store, get_folder_offline, folder != NULL, error);
 		return folder;
 
 	case CAMEL_DISCO_STORE_RESYNCING:
-		folder = class->get_folder_resyncing (store, name, flags, error);
+		folder = class->get_folder_resyncing (
+			store, name, flags, cancellable, error);
 		CAMEL_CHECK_GERROR (store, get_folder_resyncing, folder != NULL, error);
 		return folder;
 	}
@@ -188,6 +200,7 @@ static CamelFolderInfo *
 disco_store_get_folder_info (CamelStore *store,
                              const gchar *top,
                              guint32 flags,
+                             GCancellable *cancellable,
                              GError **error)
 {
 	CamelDiscoStore *disco_store = CAMEL_DISCO_STORE (store);
@@ -201,7 +214,8 @@ disco_store_get_folder_info (CamelStore *store,
 
 	switch (camel_disco_store_status (disco_store)) {
 	case CAMEL_DISCO_STORE_ONLINE:
-		info = class->get_folder_info_online (store, top, flags, error);
+		info = class->get_folder_info_online (
+			store, top, flags, cancellable, error);
 		if (!(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED))
 			CAMEL_CHECK_GERROR (store, get_folder_info_online, info != NULL, error);
 		return info;
@@ -214,13 +228,15 @@ disco_store_get_folder_info (CamelStore *store,
 			return NULL;
 		}
 
-		info = class->get_folder_info_offline (store, top, flags, error);
+		info = class->get_folder_info_offline (
+			store, top, flags, cancellable, error);
 		if (!(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED))
 			CAMEL_CHECK_GERROR (store, get_folder_info_offline, info != NULL, error);
 		return info;
 
 	case CAMEL_DISCO_STORE_RESYNCING:
-		info = class->get_folder_info_resyncing (store, top, flags, error);
+		info = class->get_folder_info_resyncing (
+			store, top, flags, cancellable, error);
 		if (!(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED))
 			CAMEL_CHECK_GERROR (store, get_folder_info_resyncing, info != NULL, error);
 		return info;
@@ -232,6 +248,7 @@ disco_store_get_folder_info (CamelStore *store,
 static gboolean
 disco_store_set_status (CamelDiscoStore *disco_store,
                         CamelDiscoStoreStatus status,
+                        GCancellable *cancellable,
                         GError **error)
 {
 	CamelService *service = CAMEL_SERVICE (disco_store);
@@ -261,7 +278,7 @@ disco_store_set_status (CamelDiscoStore *disco_store,
 					folder = folders->pdata[i];
 					if (G_TYPE_CHECK_INSTANCE_TYPE (folder, CAMEL_TYPE_DISCO_FOLDER)
 					    && (sync || camel_disco_folder_get_offline_sync (CAMEL_DISCO_FOLDER (folder)))) {
-						camel_disco_folder_prepare_for_offline((CamelDiscoFolder *)folder, "", NULL);
+						camel_disco_folder_prepare_for_offline((CamelDiscoFolder *)folder, "", cancellable, NULL);
 					}
 					g_object_unref (folder);
 				}
@@ -269,7 +286,9 @@ disco_store_set_status (CamelDiscoStore *disco_store,
 			}
 		}
 
-		camel_store_sync (CAMEL_STORE (disco_store), FALSE, NULL);
+		camel_store_sync (
+			CAMEL_STORE (disco_store),
+			FALSE, cancellable, NULL);
 	}
 
 	if (!camel_service_disconnect (CAMEL_SERVICE (disco_store), network_available, error))
@@ -328,14 +347,16 @@ camel_disco_store_status (CamelDiscoStore *store)
  * camel_disco_store_set_status:
  * @store: a disconnectable store
  * @status: the new status
+ * @cancellable: optional #GCancellable method, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Sets @store to @status. If an error occurrs and the status cannot
- * be set to @status, @ex will be set.
+ * be set to @status, @error will be set.
  **/
 gboolean
 camel_disco_store_set_status (CamelDiscoStore *store,
                               CamelDiscoStoreStatus status,
+                              GCancellable *cancellable,
                               GError **error)
 {
 	CamelDiscoStoreClass *class;
@@ -346,7 +367,7 @@ camel_disco_store_set_status (CamelDiscoStore *store,
 	class = CAMEL_DISCO_STORE_GET_CLASS (store);
 	g_return_val_if_fail (class->set_status != NULL, FALSE);
 
-	success = class->set_status (store, status, error);
+	success = class->set_status (store, status, cancellable, error);
 	CAMEL_CHECK_GERROR (store, set_status, success, error);
 
 	return success;
@@ -402,6 +423,7 @@ camel_disco_store_check_online (CamelDiscoStore *store,
 
 void
 camel_disco_store_prepare_for_offline (CamelDiscoStore *disco_store,
+                                       GCancellable *cancellable,
                                        GError **error)
 {
 	CamelService *service;
@@ -426,7 +448,7 @@ camel_disco_store_prepare_for_offline (CamelDiscoStore *disco_store,
 					folder = folders->pdata[i];
 					if (G_TYPE_CHECK_INSTANCE_TYPE (folder, CAMEL_TYPE_DISCO_FOLDER)
 					    && (sync || camel_disco_folder_get_offline_sync (CAMEL_DISCO_FOLDER (folder)))) {
-						camel_disco_folder_prepare_for_offline((CamelDiscoFolder *)folder, "(match-all)", NULL);
+						camel_disco_folder_prepare_for_offline((CamelDiscoFolder *)folder, "(match-all)", cancellable, NULL);
 					}
 					g_object_unref (folder);
 				}
@@ -434,6 +456,8 @@ camel_disco_store_prepare_for_offline (CamelDiscoStore *disco_store,
 			}
 		}
 
-		camel_store_sync (CAMEL_STORE (disco_store), FALSE, NULL);
+		camel_store_sync (
+			CAMEL_STORE (disco_store),
+			FALSE, cancellable, NULL);
 	}
 }
diff --git a/camel/camel-disco-store.h b/camel/camel-disco-store.h
index 5a77cd9..fa17bcd 100644
--- a/camel/camel-disco-store.h
+++ b/camel/camel-disco-store.h
@@ -74,60 +74,82 @@ struct _CamelDiscoStore {
 struct _CamelDiscoStoreClass {
 	CamelStoreClass parent_class;
 
-	gboolean          (*set_status)              (CamelDiscoStore *,
-						      CamelDiscoStoreStatus,
-						      GError **error);
-	gboolean          (*can_work_offline)        (CamelDiscoStore *);
-
-	gboolean          (*connect_online)          (CamelService *,
-						      GError **error);
-	gboolean          (*connect_offline)         (CamelService *,
-						      GError **error);
-
-	gboolean          (*disconnect_online)       (CamelService *, gboolean,
-						      GError **error);
-	gboolean          (*disconnect_offline)      (CamelService *, gboolean,
-						      GError **error);
-
-	CamelFolder *     (*get_folder_online)       (CamelStore *store,
-						      const gchar *name,
-						      guint32 flags,
-						      GError **error);
-	CamelFolder *     (*get_folder_offline)      (CamelStore *store,
-						      const gchar *name,
-						      guint32 flags,
-						      GError **error);
-	CamelFolder *     (*get_folder_resyncing)    (CamelStore *store,
-						      const gchar *name,
-						      guint32 flags,
-						      GError **error);
-
-	CamelFolderInfo * (*get_folder_info_online)    (CamelStore *store,
-							const gchar *top,
-							guint32 flags,
-							GError **error);
-	CamelFolderInfo * (*get_folder_info_offline)   (CamelStore *store,
-							const gchar *top,
-							guint32 flags,
-							GError **error);
-	CamelFolderInfo * (*get_folder_info_resyncing) (CamelStore *store,
-							const gchar *top,
-							guint32 flags,
-							GError **error);
+	gboolean	(*set_status)		(CamelDiscoStore *,
+						 CamelDiscoStoreStatus,
+						 GCancellable *cancellable,
+						 GError **error);
+	gboolean	(*can_work_offline)	(CamelDiscoStore *);
+
+	gboolean	(*connect_online)	(CamelService *service,
+						 GCancellable *cancellable,
+						 GError **error);
+	gboolean	(*connect_offline)	(CamelService *service,
+						 GCancellable *cancellable,
+						 GError **error);
+
+	gboolean	(*disconnect_online)	(CamelService *service,
+						 gboolean,
+						 GCancellable *cancellable,
+						 GError **error);
+	gboolean	(*disconnect_offline)	(CamelService *service,
+						 gboolean,
+						 GCancellable *cancellable,
+						 GError **error);
+
+	CamelFolder *	(*get_folder_online)	(CamelStore *store,
+						 const gchar *name,
+						 guint32 flags,
+						 GCancellable *cancellable,
+						 GError **error);
+	CamelFolder *	(*get_folder_offline)	(CamelStore *store,
+						 const gchar *name,
+						 guint32 flags,
+						 GCancellable *cancellable,
+						 GError **error);
+	CamelFolder *	(*get_folder_resyncing)	(CamelStore *store,
+						 const gchar *name,
+						 guint32 flags,
+						 GCancellable *cancellable,
+						 GError **error);
+
+	CamelFolderInfo *
+			(*get_folder_info_online)
+						(CamelStore *store,
+						 const gchar *top,
+						 guint32 flags,
+						 GCancellable *cancellable,
+						 GError **error);
+	CamelFolderInfo *
+			(*get_folder_info_offline)
+						(CamelStore *store,
+						 const gchar *top,
+						 guint32 flags,
+						 GCancellable *cancellable,
+						 GError **error);
+	CamelFolderInfo *
+			(*get_folder_info_resyncing)
+						(CamelStore *store,
+						 const gchar *top,
+						 guint32 flags,
+						 GCancellable *cancellable,
+						 GError **error);
 };
 
-GType camel_disco_store_get_type (void);
-
-/* Public methods */
-CamelDiscoStoreStatus camel_disco_store_status           (CamelDiscoStore *store);
-gboolean              camel_disco_store_set_status       (CamelDiscoStore *store,
-							  CamelDiscoStoreStatus status,
-							  GError **error);
-gboolean              camel_disco_store_can_work_offline (CamelDiscoStore *store);
-
-/* Convenience functions */
-gboolean camel_disco_store_check_online (CamelDiscoStore *store, GError **error);
-void camel_disco_store_prepare_for_offline (CamelDiscoStore *store, GError **error);
+GType		camel_disco_store_get_type	(void);
+CamelDiscoStoreStatus
+		camel_disco_store_status	(CamelDiscoStore *store);
+gboolean	camel_disco_store_set_status	(CamelDiscoStore *store,
+						 CamelDiscoStoreStatus status,
+						 GCancellable *cancellable,
+						 GError **error);
+gboolean	camel_disco_store_can_work_offline
+						(CamelDiscoStore *store);
+gboolean	camel_disco_store_check_online	(CamelDiscoStore *store,
+						 GError **error);
+void		camel_disco_store_prepare_for_offline
+						(CamelDiscoStore *store,
+						 GCancellable *cancellable,
+						 GError **error);
 
 G_END_DECLS
 
diff --git a/camel/camel-file-utils.c b/camel/camel-file-utils.c
index 1b8a426..bdf9d81 100644
--- a/camel/camel-file-utils.c
+++ b/camel/camel-file-utils.c
@@ -403,6 +403,7 @@ camel_file_util_safe_filename (const gchar *name)
  * @fd: file descriptor
  * @buf: buffer to fill
  * @n: number of bytes to read into @buf
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Cancellable libc read() replacement.
@@ -417,25 +418,19 @@ gssize
 camel_read (gint fd,
             gchar *buf,
             gsize n,
+            GCancellable *cancellable,
             GError **error)
 {
 	gssize nread;
 	gint cancel_fd;
 
-	if (camel_operation_cancel_check (NULL)) {
+	if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
 		errno = EINTR;
-		g_set_error (
-			error, G_IO_ERROR,
-			G_IO_ERROR_CANCELLED,
-			_("Cancelled"));
 		return -1;
 	}
 
-#ifndef G_OS_WIN32
-	cancel_fd = camel_operation_cancel_fd (NULL);
-#else
-	cancel_fd = -1;
-#endif
+	cancel_fd = g_cancellable_get_fd (cancellable);
+
 	if (cancel_fd == -1) {
 		do {
 			nread = read (fd, buf, n);
@@ -481,18 +476,16 @@ camel_read (gint fd,
 #endif
 	}
 
-	if (nread == -1) {
-		if (errno == EINTR)
-			g_set_error (
-				error, G_IO_ERROR,
-				G_IO_ERROR_CANCELLED,
-				_("Cancelled"));
-		else
-			g_set_error (
-				error, G_IO_ERROR,
-				g_io_error_from_errno (errno),
-				"%s", g_strerror (errno));
-	}
+	g_cancellable_release_fd (cancellable);
+
+	if (g_cancellable_set_error_if_cancelled (cancellable, error))
+		return -1;
+
+	if (nread == -1)
+		g_set_error (
+			error, G_IO_ERROR,
+			g_io_error_from_errno (errno),
+			"%s", g_strerror (errno));
 
 	return nread;
 }
@@ -502,6 +495,7 @@ camel_read (gint fd,
  * @fd: file descriptor
  * @buf: buffer to write
  * @n: number of bytes of @buf to write
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Cancellable libc write() replacement.
@@ -516,25 +510,19 @@ gssize
 camel_write (gint fd,
              const gchar *buf,
              gsize n,
+             GCancellable *cancellable,
              GError **error)
 {
 	gssize w, written = 0;
 	gint cancel_fd;
 
-	if (camel_operation_cancel_check (NULL)) {
+	if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
 		errno = EINTR;
-		g_set_error (
-			error, G_IO_ERROR,
-			G_IO_ERROR_CANCELLED,
-			_("Cancelled"));
 		return -1;
 	}
 
-#ifndef G_OS_WIN32
-	cancel_fd = camel_operation_cancel_fd (NULL);
-#else
-	cancel_fd = -1;
-#endif
+	cancel_fd = g_cancellable_get_fd (cancellable);
+
 	if (cancel_fd == -1) {
 		do {
 			do {
@@ -591,17 +579,16 @@ camel_write (gint fd,
 #endif
 	}
 
+	g_cancellable_release_fd (cancellable);
+
+	if (g_cancellable_set_error_if_cancelled (cancellable, error))
+		return -1;
+
 	if (w == -1) {
-		if (errno == EINTR)
-			g_set_error (
-				error, G_IO_ERROR,
-				G_IO_ERROR_CANCELLED,
-				_("Cancelled"));
-		else
-			g_set_error (
-				error, G_IO_ERROR,
-				g_io_error_from_errno (errno),
-				"%s", g_strerror (errno));
+		g_set_error (
+			error, G_IO_ERROR,
+			g_io_error_from_errno (errno),
+			"%s", g_strerror (errno));
 		return -1;
 	}
 
@@ -613,6 +600,7 @@ camel_write (gint fd,
  * @fd: a socket
  * @buf: buffer to fill
  * @n: number of bytes to read into @buf
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Cancellable read() replacement for sockets. Code that intends to be
@@ -627,23 +615,21 @@ gssize
 camel_read_socket (gint fd,
                    gchar *buf,
                    gsize n,
+                   GCancellable *cancellable,
                    GError **error)
 {
 #ifndef G_OS_WIN32
-	return camel_read (fd, buf, n, error);
+	return camel_read (fd, buf, n, cancellable, error);
 #else
 	gssize nread;
 	gint cancel_fd;
 
-	if (camel_operation_cancel_check (NULL)) {
+	if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
 		errno = EINTR;
-		g_set_error (
-			error, G_IO_ERROR,
-			G_IO_ERROR_CANCELLED,
-			_("Canceled"));
 		return -1;
 	}
-	cancel_fd = camel_operation_cancel_fd (NULL);
+
+	cancel_fd = g_cancellable_get_fd (cancellable);
 
 	if (cancel_fd == -1) {
 		do {
@@ -683,18 +669,16 @@ camel_read_socket (gint fd,
 		;
 	}
 
-	if (nread == -1) {
-		if (errno == EINTR)
-			g_set_error (
-				error, G_IO_ERROR,
-				G_IO_ERROR_CANCELLED,
-				_("Cancelled"));
-		else
-			g_set_error (
-				error, G_IO_ERROR,
-				g_io_error_from_errno (errno),
-				"%s", g_strerror (errno));
-	}
+	g_cancellable_release_fd (cancellable);
+
+	if (g_cancellable_set_error_if_cancelled (cancellable, error))
+		return -1;
+
+	if (nread == -1)
+		g_set_error (
+			error, G_IO_ERROR,
+			g_io_error_from_errno (errno),
+			"%s", g_strerror (errno));
 
 	return nread;
 #endif
@@ -718,15 +702,16 @@ gssize
 camel_write_socket (gint fd,
                     const gchar *buf,
                     gsize n,
+                    GCancellable *cancellable,
                     GError **error)
 {
 #ifndef G_OS_WIN32
-	return camel_write (fd, buf, n, error);
+	return camel_write (fd, buf, n, cancellable, error);
 #else
 	gssize w, written = 0;
 	gint cancel_fd;
 
-	if (camel_operation_cancel_check (NULL)) {
+	if (g_cancellable_is_cancelled (cancellable)) {
 		errno = EINTR;
 		g_set_error (
 			error, G_IO_ERROR,
@@ -735,7 +720,8 @@ camel_write_socket (gint fd,
 		return -1;
 	}
 
-	cancel_fd = camel_operation_cancel_fd (NULL);
+	cancel_fd = g_cancellable_get_fd (cancellable);
+
 	if (cancel_fd == -1) {
 		do {
 			do {
@@ -783,17 +769,16 @@ camel_write_socket (gint fd,
 		ioctlsocket (fd, FIONBIO, &arg);
 	}
 
+	g_cancellable_release_fd (cancellable);
+
+	if (g_cancellable_set_error_if_cancelled (cancellable, error))
+		return -1;
+
 	if (w == -1) {
-		if (errno == EINTR)
-			g_set_error (
-				error, G_IO_ERROR,
-				G_IO_ERROR_CANCELLED,
-				_("Canceled"));
-		else
-			g_set_error (
-				error, G_IO_ERROR,
-				g_io_error_from_errno (errno),
-				"%s", g_strerror (errno));
+		g_set_error (
+			error, G_IO_ERROR,
+			g_io_error_from_errno (errno),
+			"%s", g_strerror (errno));
 		return -1;
 	}
 
diff --git a/camel/camel-file-utils.h b/camel/camel-file-utils.h
index 2178902..e388d34 100644
--- a/camel/camel-file-utils.h
+++ b/camel/camel-file-utils.h
@@ -30,7 +30,7 @@
 #ifndef CAMEL_FILE_UTILS_H
 #define CAMEL_FILE_UTILS_H
 
-#include <glib.h>
+#include <gio/gio.h>
 #include <stdio.h>
 #include <sys/types.h>
 #include <time.h>
@@ -66,13 +66,29 @@ gchar *camel_file_util_safe_filename (const gchar *name);
  * camel_read_socket() and camel_write_socket(). These are cancellable
  * also on Win32.
  */
-gssize camel_read (gint fd, gchar *buf, gsize n, GError **error);
-gssize camel_write (gint fd, const gchar *buf, gsize n, GError **error);
+gssize		camel_read			(gint fd,
+						 gchar *buf,
+						 gsize n,
+						 GCancellable *cancellable,
+						 GError **error);
+gssize		camel_write			(gint fd,
+						 const gchar *buf,
+						 gsize n,
+						 GCancellable *cancellable,
+						 GError **error);
 
-gssize camel_read_socket (gint fd, gchar *buf, gsize n, GError **error);
-gssize camel_write_socket (gint fd, const gchar *buf, gsize n, GError **error);
+gssize		camel_read_socket		(gint fd,
+						 gchar *buf,
+						 gsize n,
+						 GCancellable *cancellable,
+						 GError **error);
+gssize		camel_write_socket		(gint fd,
+						 const gchar *buf,
+						 gsize n,
+						 GCancellable *cancellable,
+						 GError **error);
 
-gchar *camel_file_util_savename (const gchar *filename);
+gchar *		camel_file_util_savename	(const gchar *filename);
 
 G_END_DECLS
 
diff --git a/camel/camel-filter-driver.c b/camel/camel-filter-driver.c
index 7d7f08e..5ba1eff 100644
--- a/camel/camel-filter-driver.c
+++ b/camel/camel-filter-driver.c
@@ -465,7 +465,10 @@ do_forward_to (struct _ESExp *f, gint argc, struct _ESExpResult **argv, CamelFil
 
 	/* make sure we have the message... */
 	if (p->message == NULL) {
-		if (!(p->message = camel_folder_get_message (p->source, p->uid, &p->error)))
+		/* FIXME Pass a GCancellable */
+		p->message = camel_folder_get_message (
+			p->source, p->uid, NULL, &p->error);
+		if (p->message == NULL)
 			return NULL;
 	}
 
@@ -501,16 +504,24 @@ do_copy (struct _ESExp *f, gint argc, struct _ESExpResult **argv, CamelFilterDri
 
 				uids = g_ptr_array_new ();
 				g_ptr_array_add (uids, (gchar *) p->uid);
-				camel_folder_transfer_messages_to (p->source, uids, outbox, NULL, FALSE, &p->error);
+				/* FIXME Pass a GCancellable */
+				camel_folder_transfer_messages_to (
+					p->source, uids, outbox, NULL,
+					FALSE, NULL, &p->error);
 				g_ptr_array_free (uids, TRUE);
 			} else {
 				if (p->message == NULL)
-					p->message = camel_folder_get_message (p->source, p->uid, &p->error);
+					/* FIXME Pass a GCancellable */
+					p->message = camel_folder_get_message (
+						p->source, p->uid, NULL, &p->error);
 
 				if (!p->message)
 					continue;
 
-				camel_folder_append_message (outbox, p->message, p->info, NULL, &p->error);
+				/* FIXME Pass a GCancellable */
+				camel_folder_append_message (
+					outbox, p->message, p->info,
+					NULL, NULL, &p->error);
 			}
 
 			if (p->error == NULL)
@@ -554,27 +565,38 @@ do_move (struct _ESExp *f, gint argc, struct _ESExpResult **argv, CamelFilterDri
 
 				uids = g_ptr_array_new ();
 				g_ptr_array_add (uids, (gchar *) p->uid);
+				/* FIXME Pass a GCancellable */
 				camel_folder_transfer_messages_to (
 					p->source, uids, outbox, NULL,
-					last, &p->error);
+					last, NULL, &p->error);
 				g_ptr_array_free (uids, TRUE);
 			} else {
 				if (p->message == NULL)
+					/* FIXME Pass a GCancellable */
 					p->message = camel_folder_get_message (
-						p->source, p->uid, &p->error);
+						p->source, p->uid, NULL, &p->error);
 
 				if (!p->message)
 					continue;
 
+				/* FIXME Pass a GCancellable */
 				camel_folder_append_message (
 					outbox, p->message, p->info,
-					NULL, &p->error);
+					NULL, NULL, &p->error);
 
 				if (p->error == NULL && last) {
 					if (p->source && p->uid && camel_folder_has_summary_capability (p->source))
-						camel_folder_set_message_flags (p->source, p->uid, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN, ~0);
+						camel_folder_set_message_flags (
+							p->source, p->uid,
+							CAMEL_MESSAGE_DELETED |
+							CAMEL_MESSAGE_SEEN, ~0);
 					else
-						camel_message_info_set_flags (p->info, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_FOLDER_FLAGGED, ~0);
+						camel_message_info_set_flags (
+							p->info,
+							CAMEL_MESSAGE_DELETED |
+							CAMEL_MESSAGE_SEEN |
+							CAMEL_MESSAGE_FOLDER_FLAGGED,
+							~0);
 				}
 			}
 
@@ -702,9 +724,12 @@ set_flag (struct _ESExp *f, gint argc, struct _ESExpResult **argv, CamelFilterDr
 	if (argc == 1 && argv[0]->type == ESEXP_RES_STRING) {
 		flags = camel_system_flag (argv[0]->value.string);
 		if (p->source && p->uid && camel_folder_has_summary_capability (p->source))
-			camel_folder_set_message_flags (p->source, p->uid, flags, ~0);
+			camel_folder_set_message_flags (
+				p->source, p->uid, flags, ~0);
 		else
-			camel_message_info_set_flags (p->info, flags | CAMEL_MESSAGE_FOLDER_FLAGGED, ~0);
+			camel_message_info_set_flags (
+				p->info, flags |
+				CAMEL_MESSAGE_FOLDER_FLAGGED, ~0);
 		camel_filter_driver_log (driver, FILTER_LOG_ACTION, "Set %s flag", argv[0]->value.string);
 	}
 
@@ -721,9 +746,12 @@ unset_flag (struct _ESExp *f, gint argc, struct _ESExpResult **argv, CamelFilter
 	if (argc == 1 && argv[0]->type == ESEXP_RES_STRING) {
 		flags = camel_system_flag (argv[0]->value.string);
 		if (p->source && p->uid && camel_folder_has_summary_capability (p->source))
-			camel_folder_set_message_flags (p->source, p->uid, flags, 0);
+			camel_folder_set_message_flags (
+				p->source, p->uid, flags, 0);
 		else
-			camel_message_info_set_flags (p->info, flags | CAMEL_MESSAGE_FOLDER_FLAGGED, 0);
+			camel_message_info_set_flags (
+				p->info, flags |
+				CAMEL_MESSAGE_FOLDER_FLAGGED, 0);
 		camel_filter_driver_log (driver, FILTER_LOG_ACTION, "Unset %s flag", argv[0]->value.string);
 	}
 
@@ -779,7 +807,10 @@ pipe_to_system (struct _ESExp *f, gint argc, struct _ESExpResult **argv, CamelFi
 
 	/* make sure we have the message... */
 	if (p->message == NULL) {
-		if (!(p->message = camel_folder_get_message (p->source, p->uid, &p->error)))
+		/* FIXME Pass a GCancellable */
+		p->message = camel_folder_get_message (
+			p->source, p->uid, NULL, &p->error);
+		if (p->message == NULL)
 			return -1;
 	}
 
@@ -814,13 +845,13 @@ pipe_to_system (struct _ESExp *f, gint argc, struct _ESExpResult **argv, CamelFi
 	g_ptr_array_free (args, TRUE);
 
 	stream = camel_stream_fs_new_with_fd (pipe_to_child);
-	if (camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (p->message), stream, NULL) == -1) {
+	if (camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (p->message), stream, NULL, NULL) == -1) {
 		g_object_unref (stream);
 		close (pipe_from_child);
 		goto wait;
 	}
 
-	if (camel_stream_flush (stream, NULL) == -1) {
+	if (camel_stream_flush (stream, NULL, NULL) == -1) {
 		g_object_unref (stream);
 		close (pipe_from_child);
 		goto wait;
@@ -830,7 +861,7 @@ pipe_to_system (struct _ESExp *f, gint argc, struct _ESExpResult **argv, CamelFi
 
 	stream = camel_stream_fs_new_with_fd (pipe_from_child);
 	mem = camel_stream_mem_new ();
-	if (camel_stream_write_to_stream (stream, mem, NULL) == -1) {
+	if (camel_stream_write_to_stream (stream, mem, NULL, NULL) == -1) {
 		g_object_unref (stream);
 		g_object_unref (mem);
 		goto wait;
@@ -845,7 +876,7 @@ pipe_to_system (struct _ESExp *f, gint argc, struct _ESExpResult **argv, CamelFi
 	g_object_unref (mem);
 
 	message = camel_mime_message_new ();
-	if (camel_mime_part_construct_from_parser ((CamelMimePart *) message, parser, NULL) == -1) {
+	if (camel_mime_part_construct_from_parser ((CamelMimePart *) message, parser, NULL, NULL) == -1) {
 		gint err = camel_mime_parser_errno (parser);
 		g_set_error (
 			&p->error, G_IO_ERROR,
@@ -1029,7 +1060,10 @@ close_folder (gpointer key, gpointer value, gpointer data)
 	g_free (key);
 
 	if (folder != FOLDER_INVALID) {
-		camel_folder_sync (folder, FALSE, (p->error != NULL) ? NULL : &p->error);
+		/* FIXME Pass a GCancellable */
+		camel_folder_sync (
+			folder, FALSE, NULL,
+			(p->error != NULL) ? NULL : &p->error);
 		camel_folder_thaw (folder);
 		g_object_unref (folder);
 	}
@@ -1207,6 +1241,7 @@ decode_flags_from_xev (const gchar *xev, CamelMessageInfoBase *mi)
  * @driver: CamelFilterDriver
  * @mbox: mbox filename to be filtered
  * @original_source_url:
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Filters an mbox file based on rules defined in the FilterDriver
@@ -1221,6 +1256,7 @@ gint
 camel_filter_driver_filter_mbox (CamelFilterDriver *driver,
                                  const gchar *mbox,
                                  const gchar *original_source_url,
+                                 GCancellable *cancellable,
                                  GError **error)
 {
 	struct _CamelFilterDriverPrivate *p = CAMEL_FILTER_DRIVER_GET_PRIVATE (driver);
@@ -1271,7 +1307,8 @@ camel_filter_driver_filter_mbox (CamelFilterDriver *driver,
 		message = camel_mime_message_new ();
 		mime_part = CAMEL_MIME_PART (message);
 
-		if (camel_mime_part_construct_from_parser (mime_part, mp, error) == -1) {
+		if (camel_mime_part_construct_from_parser (
+			mime_part, mp, cancellable, error) == -1) {
 			report_status (driver, CAMEL_FILTER_STATUS_END, 100, _("Failed on message %d"), i);
 			g_object_unref (message);
 			goto fail;
@@ -1288,8 +1325,8 @@ camel_filter_driver_filter_mbox (CamelFilterDriver *driver,
 		last = camel_mime_parser_tell (mp);
 		status = camel_filter_driver_filter_message (
 			driver, message, info, NULL, NULL, source_url,
-			original_source_url ? original_source_url : source_url,
-			&local_error);
+			original_source_url ? original_source_url :
+			source_url, cancellable, &local_error);
 		g_object_unref (message);
 		if (local_error != NULL || status == -1) {
 			report_status (
@@ -1310,7 +1347,7 @@ camel_filter_driver_filter_mbox (CamelFilterDriver *driver,
 
 	if (p->defaultfolder) {
 		report_status(driver, CAMEL_FILTER_STATUS_PROGRESS, 100, _("Syncing folder"));
-		camel_folder_sync (p->defaultfolder, FALSE, NULL);
+		camel_folder_sync (p->defaultfolder, FALSE, cancellable, NULL);
 	}
 
 	report_status (driver, CAMEL_FILTER_STATUS_END, 100, _("Complete"));
@@ -1331,8 +1368,10 @@ fail:
  * @driver: CamelFilterDriver
  * @folder: CamelFolder to be filtered
  * @cache: UID cache (needed for POP folders)
- * @uids: message uids to be filtered or NULL (as a shortcut to filter all messages)
+ * @uids: message uids to be filtered or NULL (as a shortcut to filter
+ *        all messages)
  * @remove: TRUE to mark filtered messages as deleted
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Filters a folder based on rules defined in the FilterDriver
@@ -1348,6 +1387,7 @@ camel_filter_driver_filter_folder (CamelFilterDriver *driver,
                                    CamelUIDCache *cache,
                                    GPtrArray *uids,
                                    gboolean remove,
+                                   GCancellable *cancellable,
                                    GError **error)
 {
 	struct _CamelFilterDriverPrivate *p = CAMEL_FILTER_DRIVER_GET_PRIVATE (driver);
@@ -1383,8 +1423,8 @@ camel_filter_driver_filter_folder (CamelFilterDriver *driver,
 			info = NULL;
 
 		status = camel_filter_driver_filter_message (
-			driver, NULL, info, uids->pdata[i],
-			folder, source_url, source_url, &local_error);
+			driver, NULL, info, uids->pdata[i], folder,
+			source_url, source_url, cancellable, &local_error);
 
 		if (camel_folder_has_summary_capability (folder))
 			camel_folder_free_message_info (folder, info);
@@ -1400,8 +1440,10 @@ camel_filter_driver_filter_folder (CamelFilterDriver *driver,
 		}
 
 		if (remove)
-			camel_folder_set_message_flags (folder, uids->pdata[i],
-							CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_SEEN, ~0);
+			camel_folder_set_message_flags (
+				folder, uids->pdata[i],
+				CAMEL_MESSAGE_DELETED |
+				CAMEL_MESSAGE_SEEN, ~0);
 
 		if (cache)
 			camel_uid_cache_save_uid (cache, uids->pdata[i]);
@@ -1409,7 +1451,7 @@ camel_filter_driver_filter_folder (CamelFilterDriver *driver,
 
 	if (p->defaultfolder) {
 		report_status (driver, CAMEL_FILTER_STATUS_PROGRESS, 100, _("Syncing folder"));
-		camel_folder_sync (p->defaultfolder, FALSE, NULL);
+		camel_folder_sync (p->defaultfolder, FALSE, cancellable, NULL);
 	}
 
 	if (i == uids->len)
@@ -1446,7 +1488,9 @@ get_message_cb (gpointer data, GError **error)
 		else
 			uid = camel_message_info_uid (p->info);
 
-		message = camel_folder_get_message (p->source, uid, error);
+		/* FIXME Pass a GCancellable */
+		message = camel_folder_get_message (
+			p->source, uid, NULL, error);
 	}
 
 	if (source_url && message && camel_mime_message_get_source (message) == NULL)
@@ -1464,6 +1508,7 @@ get_message_cb (gpointer data, GError **error)
  * @source: source folder or NULL
  * @source_url: url of source folder or NULL
  * @original_source_url: url of original source folder (pre-movemail) or NULL
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Filters a message based on rules defined in the FilterDriver
@@ -1484,6 +1529,7 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver,
                                     CamelFolder *source,
                                     const gchar *source_url,
                                     const gchar *original_source_url,
+                                    GCancellable *cancellable,
                                     GError **error)
 {
 	struct _CamelFilterDriverPrivate *p = CAMEL_FILTER_DRIVER_GET_PRIVATE (driver);
@@ -1505,7 +1551,8 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver,
 		if (message) {
 			g_object_ref (message);
 		} else {
-			message = camel_folder_get_message (source, uid, error);
+			message = camel_folder_get_message (
+				source, uid, cancellable, error);
 			if (!message)
 				return -1;
 		}
@@ -1592,9 +1639,15 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver,
 	/* *Now* we can set the DELETED flag... */
 	if (p->deleted) {
 		if (p->source && p->uid && camel_folder_has_summary_capability (p->source))
-			camel_folder_set_message_flags (p->source, p->uid, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN, ~0);
+			camel_folder_set_message_flags (
+				p->source, p->uid,
+				CAMEL_MESSAGE_DELETED |
+				CAMEL_MESSAGE_SEEN, ~0);
 		else
-			camel_message_info_set_flags (info, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_FOLDER_FLAGGED, ~0);
+			camel_message_info_set_flags (
+				info, CAMEL_MESSAGE_DELETED |
+				CAMEL_MESSAGE_SEEN |
+				CAMEL_MESSAGE_FOLDER_FLAGGED, ~0);
 	}
 
 	/* Logic: if !Moved and there exists a default folder... */
@@ -1615,18 +1668,19 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver,
 			g_ptr_array_add (uids, (gchar *) p->uid);
 			camel_folder_transfer_messages_to (
 				p->source, uids, p->defaultfolder,
-				NULL, FALSE, &p->error);
+				NULL, FALSE, cancellable, &p->error);
 			g_ptr_array_free (uids, TRUE);
 		} else {
 			if (p->message == NULL) {
-				p->message = camel_folder_get_message (source, uid, error);
+				p->message = camel_folder_get_message (
+					source, uid, cancellable, error);
 				if (!p->message)
 					goto error;
 			}
 
 			camel_folder_append_message (
 				p->defaultfolder, p->message,
-				p->info, NULL, &p->error);
+				p->info, NULL, cancellable, &p->error);
 		}
 	}
 
diff --git a/camel/camel-filter-driver.h b/camel/camel-filter-driver.h
index da22e9e..c509126 100644
--- a/camel/camel-filter-driver.h
+++ b/camel/camel-filter-driver.h
@@ -107,16 +107,29 @@ gint  camel_filter_driver_remove_rule_by_name  (CamelFilterDriver *d, const gcha
 
 void camel_filter_driver_flush                (CamelFilterDriver *driver, GError **error);
 
-gint  camel_filter_driver_filter_message       (CamelFilterDriver *driver, CamelMimeMessage *message,
-					       CamelMessageInfo *info, const gchar *uid,
-					       CamelFolder *source, const gchar *source_url,
-					       const gchar *original_source_url, GError **error);
-
-gint  camel_filter_driver_filter_mbox          (CamelFilterDriver *driver, const gchar *mbox,
-					       const gchar *original_source_url, GError **error);
-
-gint  camel_filter_driver_filter_folder        (CamelFilterDriver *driver, CamelFolder *folder, CamelUIDCache *cache,
-					       GPtrArray *uids, gboolean remove, GError **error);
+gint		camel_filter_driver_filter_message
+						(CamelFilterDriver *driver,
+						 CamelMimeMessage *message,
+						 CamelMessageInfo *info,
+						 const gchar *uid,
+						 CamelFolder *source,
+						 const gchar *source_url,
+						 const gchar *original_source_url,
+						 GCancellable *cancellable,
+						 GError **error);
+gint		camel_filter_driver_filter_mbox	(CamelFilterDriver *driver,
+						 const gchar *mbox,
+						 const gchar *original_source_url,
+						 GCancellable *cancellable,
+						 GError **error);
+gint		camel_filter_driver_filter_folder
+						(CamelFilterDriver *driver,
+						 CamelFolder *folder,
+						 CamelUIDCache *cache,
+						 GPtrArray *uids,
+						 gboolean remove,
+						 GCancellable *cancellable,
+						 GError **error);
 
 G_END_DECLS
 
diff --git a/camel/camel-filter-search.c b/camel/camel-filter-search.c
index 03f3ed9..279786d 100644
--- a/camel/camel-filter-search.c
+++ b/camel/camel-filter-search.c
@@ -591,8 +591,8 @@ run_command (struct _ESExp *f, gint argc, struct _ESExpResult **argv, FilterMess
 
 	stream = camel_stream_fs_new_with_fd (pipe_to_child);
 	camel_data_wrapper_write_to_stream (
-		CAMEL_DATA_WRAPPER (message), stream, NULL);
-	camel_stream_flush (stream, NULL);
+		CAMEL_DATA_WRAPPER (message), stream, NULL, NULL);
+	camel_stream_flush (stream, NULL, NULL);
 	g_object_unref (stream);
 
 	context = g_main_context_new ();
diff --git a/camel/camel-folder-search.c b/camel/camel-folder-search.c
index 600fb36..e8061dd 100644
--- a/camel/camel-folder-search.c
+++ b/camel/camel-folder-search.c
@@ -1045,8 +1045,9 @@ get_current_message (CamelFolderSearch *search)
 	if (!search || !search->folder || !search->current)
 		return NULL;
 
+	/* FIXME Pass a GCancellable */
 	return camel_folder_get_message (
-		search->folder, search->current->uid, NULL);
+		search->folder, search->current->uid, NULL, NULL);
 }
 
 static ESExpResult *
@@ -1432,8 +1433,8 @@ match_words_1message (CamelDataWrapper *object, struct _camel_search_words *word
 		stream = camel_stream_mem_new_with_byte_array (byte_array);
 
 		/* FIXME: The match should be part of a stream op */
-		camel_data_wrapper_decode_to_stream (containee, stream, NULL);
-		camel_stream_write (stream, "", 1, NULL);
+		camel_data_wrapper_decode_to_stream (containee, stream, NULL, NULL);
+		camel_stream_write (stream, "", 1, NULL, NULL);
 		for (i=0;i<words->len;i++) {
 			/* FIXME: This is horridly slow, and should use a real search algorithm */
 			if (camel_ustrstrcase ((const gchar *) byte_array->data, words->words[i]->word) != NULL) {
@@ -1454,13 +1455,14 @@ static gboolean
 match_words_message (CamelFolder *folder,
                      const gchar *uid,
                      struct _camel_search_words *words,
+                     GCancellable *cancellable,
                      GError **error)
 {
 	guint32 mask;
 	CamelMimeMessage *msg;
 	gint truth = FALSE;
 
-	msg = camel_folder_get_message (folder, uid, NULL);
+	msg = camel_folder_get_message (folder, uid, cancellable, error);
 	if (msg) {
 		mask = 0;
 		truth = match_words_1message ((CamelDataWrapper *)msg, words, &mask);
@@ -1473,6 +1475,7 @@ match_words_message (CamelFolder *folder,
 static GPtrArray *
 match_words_messages (CamelFolderSearch *search,
                       struct _camel_search_words *words,
+                      GCancellable *cancellable,
                       GError **error)
 {
 	gint i;
@@ -1489,8 +1492,10 @@ match_words_messages (CamelFolderSearch *search,
 		for (i=0;i<indexed->len;i++) {
 			const gchar *uid = g_ptr_array_index (indexed, i);
 
-			if (match_words_message (search->folder, uid, words, error))
-				g_ptr_array_add (matches, (gchar *)uid);
+			if (match_words_message (
+					search->folder, uid, words,
+					cancellable, error))
+				g_ptr_array_add(matches, (gchar *)uid);
 		}
 
 		g_ptr_array_free (indexed, TRUE);
@@ -1500,8 +1505,10 @@ match_words_messages (CamelFolderSearch *search,
 		for (i=0;i<v->len;i++) {
 			gchar *uid  = g_ptr_array_index (v, i);
 
-			if (match_words_message (search->folder, uid, words, error))
-				g_ptr_array_add (matches, (gchar *)uid);
+			if (match_words_message (
+				search->folder, uid, words,
+				cancellable, error))
+				g_ptr_array_add(matches, (gchar *)uid);
 		}
 	}
 
@@ -1532,7 +1539,8 @@ search_body_contains (struct _ESExp *f, gint argc, struct _ESExpResult **argv, C
 							truth = match_message_index (search->body_index, camel_message_info_uid (search->current), words->words[j]->word, error);
 					} else {
 						/* TODO: cache current message incase of multiple body search terms */
-						truth = match_words_message (search->folder, camel_message_info_uid (search->current), words, error);
+						/* FIXME Pass a GCancellable */
+						truth = match_words_message(search->folder, camel_message_info_uid(search->current), words, NULL, error);
 					}
 					camel_search_words_free (words);
 				}
@@ -1562,7 +1570,8 @@ search_body_contains (struct _ESExp *f, gint argc, struct _ESExpResult **argv, C
 					if ((words->type & CAMEL_SEARCH_WORD_COMPLEX) == 0 && search->body_index) {
 						matches = match_words_index (search, words, error);
 					} else {
-						matches = match_words_messages (search, words, error);
+						/* FIXME Pass a GCancellable */
+						matches = match_words_messages(search, words, NULL, error);
 					}
 					for (j=0;j<matches->len;j++) {
 						g_hash_table_insert (ht, matches->pdata[j], matches->pdata[j]);
@@ -1612,7 +1621,9 @@ search_body_regex (struct _ESExp *f, gint argc, struct _ESExpResult **argv, Came
 			for (i = 0; i < v->len; i++) {
 				gchar *uid = g_ptr_array_index (v, i);
 
-				message = camel_folder_get_message (search->folder, uid, NULL);
+				/* FIXME Pass a GCancellable */
+				message = camel_folder_get_message (
+					search->folder, uid, NULL, NULL);
 				if (message) {
 					if (camel_search_message_body_contains ((CamelDataWrapper *) message, &pattern)) {
 						g_ptr_array_add (r->value.ptrarray, uid);
@@ -1826,7 +1837,8 @@ search_message_location (struct _ESExp *f, gint argc, struct _ESExpResult **argv
 
 	if (argc == 1 && argv[0]->type == ESEXP_RES_STRING) {
 		if (argv[0]->value.string && search->folder && parent_store && camel_folder_get_full_name (search->folder)) {
-			CamelFolderInfo *fi = camel_store_get_folder_info (parent_store, camel_folder_get_full_name (search->folder), 0, NULL);
+			/* FIXME Pass a GCancellable */
+			CamelFolderInfo *fi = camel_store_get_folder_info (parent_store, camel_folder_get_full_name (search->folder), 0, NULL, NULL);
 			if (fi) {
 				same = g_str_equal (fi->uri ? fi->uri : "", argv[0]->value.string);
 
diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c
index 421ad9e..421f535 100644
--- a/camel/camel-folder-summary.c
+++ b/camel/camel-folder-summary.c
@@ -1634,7 +1634,8 @@ msg_update_preview (const gchar *uid, gpointer value, CamelFolder *folder)
 	full_name = camel_folder_get_full_name (folder);
 	parent_store = camel_folder_get_parent_store (folder);
 
-	msg = camel_folder_get_message (folder, uid, NULL);
+	/* FIXME Pass a GCancellable */
+	msg = camel_folder_get_message (folder, uid, NULL, NULL);
 	if (msg != NULL) {
 		if (camel_mime_message_build_preview ((CamelMimePart *)msg, (CamelMessageInfo *)info) && info->preview)
 			camel_db_write_preview_record (parent_store->cdb_w, full_name, info->uid, info->preview, NULL);
@@ -4043,8 +4044,8 @@ summary_build_content_info_message (CamelFolderSummary *s, CamelMessageInfo *msg
 			p->filter_index);
 
 		camel_data_wrapper_decode_to_stream (
-			containee, p->filter_stream, NULL);
-		camel_stream_flush (p->filter_stream, NULL);
+			containee, p->filter_stream, NULL, NULL);
+		camel_stream_flush (p->filter_stream, NULL, NULL);
 
 		camel_stream_filter_remove (
 			CAMEL_STREAM_FILTER (p->filter_stream), idx_id);
diff --git a/camel/camel-folder.c b/camel/camel-folder.c
index d27f658..101b9c9 100644
--- a/camel/camel-folder.c
+++ b/camel/camel-folder.c
@@ -102,7 +102,8 @@ static guint signals[LAST_SIGNAL];
 G_DEFINE_ABSTRACT_TYPE (CamelFolder, camel_folder, CAMEL_TYPE_OBJECT)
 
 static void
-filter_filter (CamelSession *session, CamelSessionThreadMsg *tmsg)
+filter_filter (CamelSession *session,
+               CamelSessionThreadMsg *tmsg)
 {
 	struct _folder_filter_msg *m = (struct _folder_filter_msg *) tmsg;
 	CamelMessageInfo *info;
@@ -121,44 +122,48 @@ filter_filter (CamelSession *session, CamelSessionThreadMsg *tmsg)
 	if (m->junk) {
 		/* Translators: The %s is replaced with a folder name where the operation is running. */
 		camel_operation_start (
-			NULL, ngettext (
+			tmsg->cancellable, ngettext (
 			"Learning new spam message in '%s'",
 			"Learning new spam messages in '%s'",
 			m->junk->len), full_name);
 
-		for (i = 0; i < m->junk->len; i++) {
-			CamelMimeMessage *msg = camel_folder_get_message (m->folder, m->junk->pdata[i], NULL);
+		for (i = 0; i < m->junk->len; i ++) {
+			/* FIXME Pass a GCancellable */
+			CamelMimeMessage *msg = camel_folder_get_message (
+				m->folder, m->junk->pdata[i], NULL, NULL);
 			gint pc = 100 * i / m->junk->len;
 
-			camel_operation_progress (NULL, pc);
+			camel_operation_progress (tmsg->cancellable, pc);
 
 			if (msg) {
 				camel_junk_plugin_report_junk (csp, msg);
 				g_object_unref (msg);
 			}
 		}
-		camel_operation_end (NULL);
+		camel_operation_end (tmsg->cancellable);
 	}
 
 	if (m->notjunk) {
 		/* Translators: The %s is replaced with a folder name where the operation is running. */
 		camel_operation_start (
-			NULL, ngettext (
+			tmsg->cancellable, ngettext (
 			"Learning new ham message in '%s'",
 			"Learning new ham messages in '%s'",
 			m->notjunk->len), full_name);
-		for (i = 0; i < m->notjunk->len; i++) {
-			CamelMimeMessage *msg = camel_folder_get_message (m->folder, m->notjunk->pdata[i], NULL);
+		for (i = 0; i < m->notjunk->len; i ++) {
+			/* FIXME Pass a GCancellable */
+			CamelMimeMessage *msg = camel_folder_get_message (
+				m->folder, m->notjunk->pdata[i], NULL, NULL);
 			gint pc = 100 * i / m->notjunk->len;
 
-			camel_operation_progress (NULL, pc);
+			camel_operation_progress (tmsg->cancellable, pc);
 
 			if (msg) {
 				camel_junk_plugin_report_notjunk (csp, msg);
 				g_object_unref (msg);
 			}
 		}
-		camel_operation_end (NULL);
+		camel_operation_end (tmsg->cancellable);
 	}
 
 	if (m->junk || m->notjunk)
@@ -167,7 +172,7 @@ filter_filter (CamelSession *session, CamelSessionThreadMsg *tmsg)
 	if (m->driver && m->recents) {
 		/* Translators: The %s is replaced with a folder name where the operation is running. */
 		camel_operation_start (
-			NULL, ngettext (
+			tmsg->cancellable, ngettext (
 			"Filtering new message in '%s'",
 			"Filtering new messages in '%s'",
 			m->recents->len), full_name);
@@ -191,7 +196,7 @@ filter_filter (CamelSession *session, CamelSessionThreadMsg *tmsg)
 			gchar *uid = m->recents->pdata[i];
 			gint pc = 100 * i / m->recents->len;
 
-			camel_operation_progress (NULL, pc);
+			camel_operation_progress (tmsg->cancellable, pc);
 
 			info = camel_folder_get_message_info (m->folder, uid);
 			if (info == NULL) {
@@ -199,7 +204,10 @@ filter_filter (CamelSession *session, CamelSessionThreadMsg *tmsg)
 				continue;
 			}
 
-			status = camel_filter_driver_filter_message (m->driver, NULL, info, uid, m->folder, source_url, source_url, NULL);
+			/* FIXME Pass a GCancellable */
+			status = camel_filter_driver_filter_message (
+				m->driver, NULL, info, uid, m->folder,
+				source_url, source_url, NULL, NULL);
 
 			camel_folder_free_message_info (m->folder, info);
 		}
@@ -210,7 +218,7 @@ filter_filter (CamelSession *session, CamelSessionThreadMsg *tmsg)
 
 		g_free (source_url);
 
-		camel_operation_end (NULL);
+		camel_operation_end (tmsg->cancellable);
 	}
 }
 
@@ -258,6 +266,7 @@ folder_transfer_message_to (CamelFolder *source,
                             CamelFolder *dest,
                             gchar **transferred_uid,
                             gboolean delete_original,
+                            GCancellable *cancellable,
                             GError **error)
 {
 	CamelMimeMessage *msg;
@@ -266,7 +275,7 @@ folder_transfer_message_to (CamelFolder *source,
 
 	/* Default implementation. */
 
-	msg = camel_folder_get_message (source, uid, error);
+	msg = camel_folder_get_message (source, uid, cancellable, error);
 	if (!msg)
 		return;
 
@@ -282,7 +291,8 @@ folder_transfer_message_to (CamelFolder *source,
 	camel_message_info_set_flags (info, CAMEL_MESSAGE_DELETED, 0);
 
 	camel_folder_append_message (
-		dest, msg, info, transferred_uid, &local_error);
+		dest, msg, info, transferred_uid,
+		cancellable, &local_error);
 	g_object_unref (msg);
 
 	if (local_error != NULL)
@@ -421,6 +431,7 @@ folder_finalize (GObject *object)
 
 static gboolean
 folder_refresh_info (CamelFolder *folder,
+                     GCancellable *cancellable,
                      GError **error)
 {
 	return TRUE;
@@ -673,6 +684,7 @@ folder_transfer_messages_to (CamelFolder *source,
                              CamelFolder *dest,
                              GPtrArray **transferred_uids,
                              gboolean delete_originals,
+                             GCancellable *cancellable,
                              GError **error)
 {
 	gchar **ret_uid = NULL;
@@ -685,9 +697,11 @@ folder_transfer_messages_to (CamelFolder *source,
 	}
 
 	if (delete_originals)
-		camel_operation_start (NULL, _("Moving messages"));
+		camel_operation_start (
+			cancellable, _("Moving messages"));
 	else
-		camel_operation_start (NULL, _("Copying messages"));
+		camel_operation_start (
+			cancellable, _("Copying messages"));
 
 	if (uids->len > 1) {
 		camel_folder_freeze (dest);
@@ -700,8 +714,9 @@ folder_transfer_messages_to (CamelFolder *source,
 			ret_uid = (gchar **)&((*transferred_uids)->pdata[i]);
 		folder_transfer_message_to (
 			source, uids->pdata[i], dest, ret_uid,
-			delete_originals, &local_error);
-		camel_operation_progress (NULL, i * 100 / uids->len);
+			delete_originals, cancellable, &local_error);
+		camel_operation_progress (
+			cancellable, i * 100 / uids->len);
 	}
 
 	if (uids->len > 1) {
@@ -710,7 +725,7 @@ folder_transfer_messages_to (CamelFolder *source,
 			camel_folder_thaw (source);
 	}
 
-	camel_operation_end (NULL);
+	camel_operation_end (cancellable);
 
 	if (local_error != NULL)
 		g_propagate_error (error, local_error);
@@ -753,7 +768,7 @@ folder_freeze (CamelFolder *folder)
 }
 
 static void
-folder_thaw (CamelFolder * folder)
+folder_thaw (CamelFolder *folder)
 {
 	CamelFolderChangeInfo *info = NULL;
 
@@ -835,7 +850,9 @@ folder_changed (CamelFolder *folder,
 					g_ptr_array_add (notjunk, g_strdup (info->uid_changed->pdata[i]));
 				}
 				/* reset junk learn flag so that we don't process it again*/
-				camel_folder_set_message_flags (folder, info->uid_changed->pdata[i], CAMEL_MESSAGE_JUNK_LEARN, 0);
+				camel_folder_set_message_flags (
+					folder, info->uid_changed->pdata [i],
+					CAMEL_MESSAGE_JUNK_LEARN, 0);
 			}
 		}
 	}
@@ -1098,6 +1115,7 @@ camel_folder_get_filename (CamelFolder *folder,
  * camel_folder_sync:
  * @folder: a #CamelFolder
  * @expunge: whether or not to expunge deleted messages
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Sync changes made to a folder to its backing store, possibly
@@ -1108,6 +1126,7 @@ camel_folder_get_filename (CamelFolder *folder,
 gboolean
 camel_folder_sync (CamelFolder *folder,
                    gboolean expunge,
+                   GCancellable *cancellable,
                    GError **error)
 {
 	CamelFolderClass *class;
@@ -1121,7 +1140,7 @@ camel_folder_sync (CamelFolder *folder,
 	camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
 
 	if (!(folder->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED)) {
-		success = class->sync (folder, expunge, error);
+		success = class->sync (folder, expunge, cancellable, error);
 		CAMEL_CHECK_GERROR (folder, sync, success, error);
 	}
 
@@ -1133,6 +1152,7 @@ camel_folder_sync (CamelFolder *folder,
 /**
  * camel_folder_refresh_info:
  * @folder: a #CamelFolder
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Updates a folder's summary to be in sync with its backing store.
@@ -1141,6 +1161,7 @@ camel_folder_sync (CamelFolder *folder,
  **/
 gboolean
 camel_folder_refresh_info (CamelFolder *folder,
+                           GCancellable *cancellable,
                            GError **error)
 {
 	CamelFolderClass *class;
@@ -1153,7 +1174,7 @@ camel_folder_refresh_info (CamelFolder *folder,
 
 	camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
 
-	success = class->refresh_info (folder, error);
+	success = class->refresh_info (folder, cancellable, error);
 	CAMEL_CHECK_GERROR (folder, refresh_info, success, error);
 
 	camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
@@ -1296,6 +1317,7 @@ camel_folder_get_parent_store (CamelFolder *folder)
 /**
  * camel_folder_expunge:
  * @folder: a #CamelFolder
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Delete messages which have been marked as "DELETED"
@@ -1304,6 +1326,7 @@ camel_folder_get_parent_store (CamelFolder *folder)
  **/
 gboolean
 camel_folder_expunge (CamelFolder *folder,
+                      GCancellable *cancellable,
                       GError **error)
 {
 	CamelFolderClass *class;
@@ -1317,7 +1340,7 @@ camel_folder_expunge (CamelFolder *folder,
 	camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
 
 	if (!(folder->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED)) {
-		success = class->expunge (folder, error);
+		success = class->expunge (folder, cancellable, error);
 		CAMEL_CHECK_GERROR (folder, expunge, success, error);
 	}
 
@@ -1387,6 +1410,7 @@ camel_folder_get_deleted_message_count (CamelFolder *folder)
  * new message, or %NULL
  * @appended_uid: if non-%NULL, the UID of the appended message will
  * be returned here, if it is known.
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Append @message to @folder. Only the flag and tag data from @info
@@ -1399,6 +1423,7 @@ camel_folder_append_message (CamelFolder *folder,
                              CamelMimeMessage *message,
                              const CamelMessageInfo *info,
                              gchar **appended_uid,
+                             GCancellable *cancellable,
                              GError **error)
 {
 	CamelFolderClass *class;
@@ -1413,7 +1438,7 @@ camel_folder_append_message (CamelFolder *folder,
 	camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
 
 	success = class->append_message (
-		folder, message, info, appended_uid, error);
+		folder, message, info, appended_uid, cancellable, error);
 	CAMEL_CHECK_GERROR (folder, append_message, success, error);
 
 	camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
@@ -1727,6 +1752,7 @@ camel_folder_has_summary_capability (CamelFolder *folder)
  * camel_folder_get_message:
  * @folder: a #CamelFolder
  * @uid: the UID
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Get a message from its UID in the folder.
@@ -1736,6 +1762,7 @@ camel_folder_has_summary_capability (CamelFolder *folder)
 CamelMimeMessage *
 camel_folder_get_message (CamelFolder *folder,
                           const gchar *uid,
+                          GCancellable *cancellable,
                           GError **error)
 {
 	CamelFolderClass *class;
@@ -1747,13 +1774,18 @@ camel_folder_get_message (CamelFolder *folder,
 	class = CAMEL_FOLDER_GET_CLASS (folder);
 	g_return_val_if_fail (class->get_message != NULL, NULL);
 
+	camel_operation_start (
+		cancellable, _("Retrieving message '%s'"), uid);
+
 	camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
 
-	ret = class->get_message (folder, uid, error);
+	ret = class->get_message (folder, uid, cancellable, error);
 	CAMEL_CHECK_GERROR (folder, get_message, ret != NULL, error);
 
 	camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
 
+	camel_operation_end (cancellable);
+
 	if (ret && camel_debug_start (":folder")) {
 		printf ("CamelFolder:get_message ('%s', '%s') =\n",
 			camel_folder_get_full_name (folder), uid);
@@ -1768,6 +1800,7 @@ camel_folder_get_message (CamelFolder *folder,
  * camel_folder_sync_message:
  * @folder: a #CamelFolder
  * @uid: the UID
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Ensure that a message identified by UID has been synced in the folder (so
@@ -1780,6 +1813,7 @@ camel_folder_get_message (CamelFolder *folder,
 gboolean
 camel_folder_sync_message (CamelFolder *folder,
                            const gchar *uid,
+                           GCancellable *cancellable,
                            GError **error)
 {
 	CamelFolderClass *class;
@@ -1795,12 +1829,13 @@ camel_folder_sync_message (CamelFolder *folder,
 
 	/* Use the sync_message method if the class implements it. */
 	if (class->sync_message != NULL) {
-		success = class->sync_message (folder, uid, error);
+		success = class->sync_message (
+			folder, uid, cancellable, error);
 		CAMEL_CHECK_GERROR (folder, sync_message, success, error);
 	} else {
 		CamelMimeMessage *message;
 
-		message = class->get_message (folder, uid, error);
+		message = class->get_message (folder, uid, cancellable, error);
 		CAMEL_CHECK_GERROR (folder, get_message, message != NULL, error);
 
 		if (message != NULL) {
@@ -2139,6 +2174,7 @@ camel_folder_search_free (CamelFolder *folder,
  * @transferred_uids: if non-%NULL, the UIDs of the resulting messages
  * in @dest will be stored here, if known.
  * @delete_originals: whether or not to delete the original messages
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * This copies or moves messages from one folder to another. If the
@@ -2153,6 +2189,7 @@ camel_folder_transfer_messages_to (CamelFolder *source,
                                    CamelFolder *dest,
                                    GPtrArray **transferred_uids,
                                    gboolean delete_originals,
+                                   GCancellable *cancellable,
                                    GError **error)
 {
 	CamelFolderClass *class;
@@ -2176,11 +2213,11 @@ camel_folder_transfer_messages_to (CamelFolder *source,
 			class = CAMEL_FOLDER_GET_CLASS (source);
 		success = class->transfer_messages_to (
 			source, uids, dest, transferred_uids,
-			delete_originals, error);
+			delete_originals, cancellable, error);
 	} else
 		success = folder_transfer_messages_to (
 			source, uids, dest, transferred_uids,
-			delete_originals, error);
+			delete_originals, cancellable, error);
 
 	return success;
 }
diff --git a/camel/camel-folder.h b/camel/camel-folder.h
index 97a8fe8..1dff41a 100644
--- a/camel/camel-folder.h
+++ b/camel/camel-folder.h
@@ -145,24 +145,29 @@ struct _CamelFolderClass {
 
 	/* Methods */
 	gboolean	(*refresh_info)		(CamelFolder *folder,
+						 GCancellable *cancellable,
 						 GError **error);
 	gboolean	(*sync)			(CamelFolder *folder,
 						 gboolean expunge,
+						 GCancellable *cancellable,
 						 GError **error);
 	gboolean	(*expunge)		(CamelFolder *folder,
+						 GCancellable *cancellable,
 						 GError **error);
 	gint		(*get_message_count)	(CamelFolder *folder);
 	gboolean	(*append_message)	(CamelFolder *folder,
 						 CamelMimeMessage *message,
 						 const CamelMessageInfo *info,
 						 gchar **appended_uid,
+						 GCancellable *cancellable,
 						 GError **error);
 	guint32		(*get_permanent_flags)	(CamelFolder *folder);
 	guint32		(*get_message_flags)	(CamelFolder *folder,
 						 const gchar *uid);
 	gboolean	(*set_message_flags)	(CamelFolder *folder,
 						 const gchar *uid,
-						 guint32 flags, guint32 set);
+						 guint32 flags,
+						 guint32 set);
 	gboolean	(*get_message_user_flag)(CamelFolder *folder,
 						 const gchar *uid,
 						 const gchar *name);
@@ -180,6 +185,7 @@ struct _CamelFolderClass {
 	CamelMimeMessage *
 			(*get_message)		(CamelFolder *folder,
 						 const gchar *uid,
+						 GCancellable *cancellable,
 						 GError **error);
 	GPtrArray *	(*get_uids)		(CamelFolder *folder);
 	void		(*free_uids)		(CamelFolder *folder,
@@ -214,6 +220,7 @@ struct _CamelFolderClass {
 						 CamelFolder *destination,
 						 GPtrArray **transferred_uids,
 						 gboolean delete_originals,
+						 GCancellable *cancellable,
 						 GError **error);
 	void		(*delete)		(CamelFolder *folder);
 	void		(*rename)		(CamelFolder *folder,
@@ -228,6 +235,7 @@ struct _CamelFolderClass {
 						 GError **error);
 	gboolean	(*sync_message)		(CamelFolder *folder,
 						 const gchar *uid,
+						 GCancellable *cancellable,
 						 GError **error);
 	GPtrArray *	(*get_uncached_uids)	(CamelFolder *folder,
 						 GPtrArray *uids,
@@ -247,9 +255,11 @@ struct _CamelFolderClass {
 GType		camel_folder_get_type		(void);
 GQuark		camel_folder_error_quark	(void) G_GNUC_CONST;
 gboolean	camel_folder_refresh_info	(CamelFolder *folder,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_folder_sync		(CamelFolder *folder,
 						 gboolean expunge,
+						 GCancellable *cancellable,
 						 GError **error);
 void		camel_folder_set_lock_async	(CamelFolder *folder,
 						 gboolean skip_folder_lock);
@@ -259,6 +269,7 @@ struct _CamelStore *
 
 /* delete operations */
 gboolean	camel_folder_expunge		(CamelFolder *folder,
+						 GCancellable *cancellable,
 						 GError **error);
 
 /* folder name operations */
@@ -312,6 +323,7 @@ gboolean	camel_folder_append_message	(CamelFolder *folder,
 						 CamelMimeMessage *message,
 						 const CamelMessageInfo *info,
 						 gchar **appended_uid,
+						 GCancellable *cancellable,
 						 GError **error);
 
 /* summary related operations */
@@ -336,15 +348,18 @@ void		camel_folder_free_summary	(CamelFolder *folder,
 CamelMimeMessage *
 		camel_folder_get_message	(CamelFolder *folder,
 						 const gchar *uid,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_folder_sync_message	(CamelFolder *folder,
 						 const gchar *uid,
+						 GCancellable *cancellable,
 						 GError **error);
 
 #define camel_folder_delete_message(folder, uid) \
-	(camel_folder_set_message_flags \
-	(folder, uid, CAMEL_MESSAGE_DELETED | \
-	CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN))
+	(camel_folder_set_message_flags ( \
+		folder, uid, \
+		CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_SEEN, \
+		CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_SEEN))
 
 GPtrArray *	camel_folder_get_uids		(CamelFolder *folder);
 void		camel_folder_free_uids		(CamelFolder *folder,
@@ -392,6 +407,7 @@ gboolean	camel_folder_transfer_messages_to
 						 CamelFolder *dest,
 						 GPtrArray **transferred_uids,
 						 gboolean delete_originals,
+						 GCancellable *cancellable,
 						 GError **error);
 
 void		camel_folder_delete		(CamelFolder *folder);
diff --git a/camel/camel-gpg-context.c b/camel/camel-gpg-context.c
index 51b3cfa..9f26313 100644
--- a/camel/camel-gpg-context.c
+++ b/camel/camel-gpg-context.c
@@ -88,61 +88,6 @@ enum {
 
 G_DEFINE_TYPE (CamelGpgContext, camel_gpg_context, CAMEL_TYPE_CIPHER_CONTEXT)
 
-static const gchar *
-gpg_hash_to_id (CamelCipherContext *context, CamelCipherHash hash)
-{
-	switch (hash) {
-	case CAMEL_CIPHER_HASH_MD2:
-		return "pgp-md2";
-	case CAMEL_CIPHER_HASH_MD5:
-		return "pgp-md5";
-	case CAMEL_CIPHER_HASH_SHA1:
-	case CAMEL_CIPHER_HASH_DEFAULT:
-		return "pgp-sha1";
-	case CAMEL_CIPHER_HASH_SHA256:
-		return "pgp-sha256";
-	case CAMEL_CIPHER_HASH_SHA384:
-		return "pgp-sha384";
-	case CAMEL_CIPHER_HASH_SHA512:
-		return "pgp-sha512";
-	case CAMEL_CIPHER_HASH_RIPEMD160:
-		return "pgp-ripemd160";
-	case CAMEL_CIPHER_HASH_TIGER192:
-		return "pgp-tiger192";
-	case CAMEL_CIPHER_HASH_HAVAL5160:
-		return "pgp-haval-5-160";
-	}
-
-	return NULL;
-}
-
-static CamelCipherHash
-gpg_id_to_hash (CamelCipherContext *context, const gchar *id)
-{
-	if (id) {
-		if (!strcmp (id, "pgp-md2"))
-			return CAMEL_CIPHER_HASH_MD2;
-		else if (!strcmp (id, "pgp-md5"))
-			return CAMEL_CIPHER_HASH_MD5;
-		else if (!strcmp (id, "pgp-sha1"))
-			return CAMEL_CIPHER_HASH_SHA1;
-		else if (!strcmp (id, "pgp-sha256"))
-			return CAMEL_CIPHER_HASH_SHA256;
-		else if (!strcmp (id, "pgp-sha384"))
-			return CAMEL_CIPHER_HASH_SHA384;
-		else if (!strcmp (id, "pgp-sha512"))
-			return CAMEL_CIPHER_HASH_SHA512;
-		else if (!strcmp (id, "pgp-ripemd160"))
-			return CAMEL_CIPHER_HASH_RIPEMD160;
-		else if (!strcmp (id, "tiger192"))
-			return CAMEL_CIPHER_HASH_TIGER192;
-		else if (!strcmp (id, "haval-5-160"))
-			return CAMEL_CIPHER_HASH_HAVAL5160;
-	}
-
-	return CAMEL_CIPHER_HASH_DEFAULT;
-}
-
 enum _GpgCtxMode {
 	GPG_CTX_MODE_SIGN,
 	GPG_CTX_MODE_VERIFY,
@@ -385,7 +330,7 @@ gpg_ctx_get_diagnostics (struct _GpgCtx *gpg)
 {
 	if (!gpg->diagflushed) {
 		gpg->diagflushed = TRUE;
-		camel_stream_flush (gpg->diagnostics, NULL);
+		camel_stream_flush (gpg->diagnostics, NULL, NULL);
 		if (gpg->diagbuf->len == 0)
 			return NULL;
 
@@ -1122,11 +1067,12 @@ gpg_ctx_op_cancel (struct _GpgCtx *gpg)
 
 static gint
 gpg_ctx_op_step (struct _GpgCtx *gpg,
+                 GCancellable *cancellable,
                  GError **error)
 {
 #ifndef G_OS_WIN32
 	GPollFD polls[6];
-	gint status, i, cancel_fd;
+	gint status, i;
 	gboolean read_data = FALSE, wrote_data = FALSE;
 
 	for (i=0;i<6;i++) {
@@ -1153,8 +1099,7 @@ gpg_ctx_op_step (struct _GpgCtx *gpg,
 	polls[3].events = G_IO_OUT;
 	polls[4].fd = gpg->passwd_fd;
 	polls[4].events = G_IO_OUT;
-	cancel_fd = camel_operation_cancel_fd (NULL);
-	polls[5].fd = cancel_fd;
+	polls[5].fd = g_cancellable_get_fd (cancellable);
 	polls[5].events = G_IO_IN;
 
 	do {
@@ -1168,13 +1113,10 @@ gpg_ctx_op_step (struct _GpgCtx *gpg,
 	else if (status == -1)
 		goto exception;
 
-	if ((polls[5].revents & G_IO_IN) && camel_operation_cancel_check (NULL)) {
-		g_set_error (
-			error, G_IO_ERROR,
-			G_IO_ERROR_CANCELLED,
-			_("Cancelled"));
-		gpg_ctx_op_cancel (gpg);
+	if ((polls[5].revents & G_IO_IN) &&
+		g_cancellable_set_error_if_cancelled (cancellable, error)) {
 
+		gpg_ctx_op_cancel(gpg);
 		return -1;
 	}
 
@@ -1221,7 +1163,8 @@ gpg_ctx_op_step (struct _GpgCtx *gpg,
 
 		if (nread > 0) {
 			gsize written = camel_stream_write (
-				gpg->ostream, buffer, (gsize) nread, error);
+				gpg->ostream, buffer, (gsize)
+				nread, cancellable, error);
 			if (written != nread)
 				return -1;
 		} else {
@@ -1244,7 +1187,9 @@ gpg_ctx_op_step (struct _GpgCtx *gpg,
 			goto exception;
 
 		if (nread > 0) {
-			camel_stream_write (gpg->diagnostics, buffer, nread, error);
+			camel_stream_write (
+				gpg->diagnostics, buffer,
+				nread, cancellable, error);
 		} else {
 			gpg->seen_eof2 = TRUE;
 		}
@@ -1286,7 +1231,8 @@ gpg_ctx_op_step (struct _GpgCtx *gpg,
 
 		/* write our stream to gpg's stdin */
 		nread = camel_stream_read (
-			gpg->istream, buffer, sizeof (buffer), NULL);
+			gpg->istream, buffer,
+			sizeof (buffer), cancellable, NULL);
 		if (nread > 0) {
 			gssize w, nwritten = 0;
 
@@ -1402,12 +1348,171 @@ gpg_ctx_op_wait (struct _GpgCtx *gpg)
 #endif
 }
 
+static gchar *
+swrite (CamelMimePart *sigpart,
+        GCancellable *cancellable,
+        GError **error)
+{
+	CamelStream *ostream;
+	gchar *template;
+	gint fd, ret;
+
+	template = g_build_filename (g_get_tmp_dir (), "evolution-pgp.XXXXXX", NULL);
+	if ((fd = g_mkstemp (template)) == -1) {
+		g_free (template);
+		return NULL;
+	}
+
+	/* TODO: This should probably just write the decoded message content out, not the part + headers */
+
+	ostream = camel_stream_fs_new_with_fd (fd);
+	ret = camel_data_wrapper_write_to_stream (
+		CAMEL_DATA_WRAPPER (sigpart), ostream, cancellable, error);
+	if (ret != -1) {
+		ret = camel_stream_flush (ostream, cancellable, error);
+		if (ret != -1)
+			ret = camel_stream_close (ostream, cancellable, error);
+	}
+
+	g_object_unref (ostream);
+
+	if (ret == -1) {
+		g_unlink (template);
+		g_free (template);
+		return NULL;
+	}
+
+	return template;
+}
+
+static void
+add_signers (CamelCipherValidity *validity, const GString *signers)
+{
+	CamelInternetAddress *address;
+	gint i, count;
+
+	g_return_if_fail (validity != NULL);
+
+	if (!signers || !signers->str || !*signers->str)
+		return;
+
+	address = camel_internet_address_new ();
+	g_return_if_fail (address != NULL);
+
+	count = camel_address_decode (CAMEL_ADDRESS (address), signers->str);
+	for (i = 0; i < count; i++) {
+		const gchar *name = NULL, *email = NULL;
+
+		if (!camel_internet_address_get (address, i, &name, &email))
+			break;
+
+		camel_cipher_validity_add_certinfo (validity, CAMEL_CIPHER_VALIDITY_SIGN, name, email);
+	}
+
+	g_object_unref (address);
+}
+
+/* ********************************************************************** */
+
+static void
+gpg_context_set_property (GObject *object,
+                          guint property_id,
+                          const GValue *value,
+                          GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_ALWAYS_TRUST:
+			camel_gpg_context_set_always_trust (
+				CAMEL_GPG_CONTEXT (object),
+				g_value_get_boolean (value));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+gpg_context_get_property (GObject *object,
+                          guint property_id,
+                          GValue *value,
+                          GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_ALWAYS_TRUST:
+			g_value_set_boolean (
+				value,
+				camel_gpg_context_get_always_trust (
+				CAMEL_GPG_CONTEXT (object)));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static const gchar *
+gpg_hash_to_id (CamelCipherContext *context,
+                CamelCipherHash hash)
+{
+	switch (hash) {
+	case CAMEL_CIPHER_HASH_MD2:
+		return "pgp-md2";
+	case CAMEL_CIPHER_HASH_MD5:
+		return "pgp-md5";
+	case CAMEL_CIPHER_HASH_SHA1:
+	case CAMEL_CIPHER_HASH_DEFAULT:
+		return "pgp-sha1";
+	case CAMEL_CIPHER_HASH_SHA256:
+		return "pgp-sha256";
+	case CAMEL_CIPHER_HASH_SHA384:
+		return "pgp-sha384";
+	case CAMEL_CIPHER_HASH_SHA512:
+		return "pgp-sha512";
+	case CAMEL_CIPHER_HASH_RIPEMD160:
+		return "pgp-ripemd160";
+	case CAMEL_CIPHER_HASH_TIGER192:
+		return "pgp-tiger192";
+	case CAMEL_CIPHER_HASH_HAVAL5160:
+		return "pgp-haval-5-160";
+	}
+
+	return NULL;
+}
+
+static CamelCipherHash
+gpg_id_to_hash (CamelCipherContext *context,
+                const gchar *id)
+{
+	if (id) {
+		if (!strcmp (id, "pgp-md2"))
+			return CAMEL_CIPHER_HASH_MD2;
+		else if (!strcmp (id, "pgp-md5"))
+			return CAMEL_CIPHER_HASH_MD5;
+		else if (!strcmp (id, "pgp-sha1"))
+			return CAMEL_CIPHER_HASH_SHA1;
+		else if (!strcmp (id, "pgp-sha256"))
+			return CAMEL_CIPHER_HASH_SHA256;
+		else if (!strcmp (id, "pgp-sha384"))
+			return CAMEL_CIPHER_HASH_SHA384;
+		else if (!strcmp (id, "pgp-sha512"))
+			return CAMEL_CIPHER_HASH_SHA512;
+		else if (!strcmp (id, "pgp-ripemd160"))
+			return CAMEL_CIPHER_HASH_RIPEMD160;
+		else if (!strcmp (id, "tiger192"))
+			return CAMEL_CIPHER_HASH_TIGER192;
+		else if (!strcmp (id, "haval-5-160"))
+			return CAMEL_CIPHER_HASH_HAVAL5160;
+	}
+
+	return CAMEL_CIPHER_HASH_DEFAULT;
+}
+
 static gint
 gpg_sign (CamelCipherContext *context,
           const gchar *userid,
           CamelCipherHash hash,
           CamelMimePart *ipart,
           CamelMimePart *opart,
+          GCancellable *cancellable,
           GError **error)
 {
 	struct _GpgCtx *gpg = NULL;
@@ -1429,7 +1534,7 @@ gpg_sign (CamelCipherContext *context,
 		ipart, CAMEL_MIME_FILTER_CANON_STRIP |
 		CAMEL_MIME_FILTER_CANON_CRLF |
 		CAMEL_MIME_FILTER_CANON_FROM,
-		istream, error) == -1) {
+		istream, NULL, error) == -1) {
 		g_prefix_error (
 			error, _("Could not generate signing data: "));
 		goto fail;
@@ -1465,7 +1570,7 @@ gpg_sign (CamelCipherContext *context,
 		goto fail;
 
 	while (!gpg_ctx_op_complete (gpg)) {
-		if (gpg_ctx_op_step (gpg, error) == -1) {
+		if (gpg_ctx_op_step (gpg, cancellable, error) == -1) {
 			gpg_ctx_op_cancel (gpg);
 			goto fail;
 		}
@@ -1487,7 +1592,7 @@ gpg_sign (CamelCipherContext *context,
 
 	dw = camel_data_wrapper_new ();
 	camel_stream_reset (ostream, NULL);
-	camel_data_wrapper_construct_from_stream (dw, ostream, NULL);
+	camel_data_wrapper_construct_from_stream (dw, ostream, NULL, NULL);
 
 	sigpart = camel_mime_part_new ();
 	ct = camel_content_type_new("application", "pgp-signature");
@@ -1523,72 +1628,10 @@ fail:
 	return res;
 }
 
-static gchar *
-swrite (CamelMimePart *sigpart,
-        GError **error)
-{
-	CamelStream *ostream;
-	gchar *template;
-	gint fd, ret;
-
-	template = g_build_filename (g_get_tmp_dir (), "evolution-pgp.XXXXXX", NULL);
-	if ((fd = g_mkstemp (template)) == -1) {
-		g_free (template);
-		return NULL;
-	}
-
-	/* TODO: This should probably just write the decoded message content out, not the part + headers */
-
-	ostream = camel_stream_fs_new_with_fd (fd);
-	ret = camel_data_wrapper_write_to_stream (
-		CAMEL_DATA_WRAPPER (sigpart), ostream, error);
-	if (ret != -1) {
-		ret = camel_stream_flush (ostream, error);
-		if (ret != -1)
-			ret = camel_stream_close (ostream, error);
-	}
-
-	g_object_unref (ostream);
-
-	if (ret == -1) {
-		g_unlink (template);
-		g_free (template);
-		return NULL;
-	}
-
-	return template;
-}
-
-static void
-add_signers (CamelCipherValidity *validity, const GString *signers)
-{
-	CamelInternetAddress *address;
-	gint i, count;
-
-	g_return_if_fail (validity != NULL);
-
-	if (!signers || !signers->str || !*signers->str)
-		return;
-
-	address = camel_internet_address_new ();
-	g_return_if_fail (address != NULL);
-
-	count = camel_address_decode (CAMEL_ADDRESS (address), signers->str);
-	for (i = 0; i < count; i++) {
-		const gchar *name = NULL, *email = NULL;
-
-		if (!camel_internet_address_get (address, i, &name, &email))
-			break;
-
-		camel_cipher_validity_add_certinfo (validity, CAMEL_CIPHER_VALIDITY_SIGN, name, email);
-	}
-
-	g_object_unref (address);
-}
-
 static CamelCipherValidity *
 gpg_verify (CamelCipherContext *context,
             CamelMimePart *ipart,
+            GCancellable *cancellable,
             GError **error)
 {
 	CamelCipherContextClass *class;
@@ -1645,7 +1688,8 @@ gpg_verify (CamelCipherContext *context,
 		CamelDataWrapper *content;
 		content = camel_medium_get_content ((CamelMedium *) ipart);
 		istream = camel_stream_mem_new ();
-		camel_data_wrapper_decode_to_stream (content, istream, NULL);
+		camel_data_wrapper_decode_to_stream (
+			content, istream, NULL, NULL);
 		camel_stream_reset (istream, NULL);
 		sigpart = NULL;
 	} else {
@@ -1689,7 +1733,7 @@ gpg_verify (CamelCipherContext *context,
 #endif
 
 	if (sigpart) {
-		sigfile = swrite (sigpart, error);
+		sigfile = swrite (sigpart, cancellable, error);
 		if (sigfile == NULL) {
 			g_prefix_error (
 				error, _("Cannot verify message signature: "));
@@ -1706,7 +1750,7 @@ gpg_verify (CamelCipherContext *context,
 	camel_stream_filter_add (CAMEL_STREAM_FILTER (filter), canon);
 	g_object_unref (canon);
 
-	camel_stream_write_to_stream (istream, filter, NULL);
+	camel_stream_write_to_stream (istream, filter, NULL, NULL);
 
 	g_object_unref (filter);
 	camel_stream_reset (istream, NULL);
@@ -1723,7 +1767,7 @@ gpg_verify (CamelCipherContext *context,
 		goto exception;
 
 	while (!gpg_ctx_op_complete (gpg)) {
-		if (gpg_ctx_op_step (gpg, error) == -1) {
+		if (gpg_ctx_op_step (gpg, cancellable, error) == -1) {
 			gpg_ctx_op_cancel (gpg);
 			goto exception;
 		}
@@ -1792,6 +1836,7 @@ gpg_encrypt (CamelCipherContext *context,
              GPtrArray *recipients,
              CamelMimePart *ipart,
              CamelMimePart *opart,
+             GCancellable *cancellable,
              GError **error)
 {
 	CamelCipherContextClass *class;
@@ -1809,7 +1854,7 @@ gpg_encrypt (CamelCipherContext *context,
 	ostream = camel_stream_mem_new ();
 	istream = camel_stream_mem_new ();
 	if (camel_cipher_canonical_to_stream (
-		ipart, CAMEL_MIME_FILTER_CANON_CRLF, istream, error) == -1) {
+		ipart, CAMEL_MIME_FILTER_CANON_CRLF, istream, NULL, error) == -1) {
 		g_prefix_error (
 			error, _("Could not generate encrypting data: "));
 		goto fail1;
@@ -1831,8 +1876,8 @@ gpg_encrypt (CamelCipherContext *context,
 		goto fail;
 
 	/* FIXME: move this to a common routine */
-	while (!gpg_ctx_op_complete (gpg)) {
-		if (gpg_ctx_op_step (gpg, error) == -1) {
+	while (!gpg_ctx_op_complete(gpg)) {
+		if (gpg_ctx_op_step (gpg, cancellable, error) == -1) {
 			gpg_ctx_op_cancel (gpg);
 			goto fail;
 		}
@@ -1852,7 +1897,7 @@ gpg_encrypt (CamelCipherContext *context,
 	res = 0;
 
 	dw = camel_data_wrapper_new ();
-	camel_data_wrapper_construct_from_stream (dw, ostream, NULL);
+	camel_data_wrapper_construct_from_stream (dw, ostream, NULL, NULL);
 
 	encpart = camel_mime_part_new ();
 	ct = camel_content_type_new("application", "octet-stream");
@@ -1866,13 +1911,13 @@ gpg_encrypt (CamelCipherContext *context,
 	camel_mime_part_set_description(encpart, _("This is a digitally encrypted message part"));
 
 	vstream = camel_stream_mem_new ();
-	camel_stream_write (vstream, "Version: 1\n", strlen("Version: 1\n"), NULL);
+	camel_stream_write_string (vstream, "Version: 1\n", NULL, NULL);
 	camel_stream_reset (vstream, NULL);
 
 	verpart = camel_mime_part_new ();
 	dw = camel_data_wrapper_new ();
 	camel_data_wrapper_set_mime_type (dw, class->encrypt_protocol);
-	camel_data_wrapper_construct_from_stream (dw, vstream, NULL);
+	camel_data_wrapper_construct_from_stream (dw, vstream, NULL, NULL);
 	g_object_unref (vstream);
 	camel_medium_set_content ((CamelMedium *)verpart, dw);
 	g_object_unref (dw);
@@ -1905,6 +1950,7 @@ static CamelCipherValidity *
 gpg_decrypt (CamelCipherContext *context,
              CamelMimePart *ipart,
              CamelMimePart *opart,
+             GCancellable *cancellable,
              GError **error)
 {
 	struct _GpgCtx *gpg;
@@ -1956,7 +2002,7 @@ gpg_decrypt (CamelCipherContext *context,
 	}
 
 	istream = camel_stream_mem_new ();
-	camel_data_wrapper_decode_to_stream (content, istream, NULL);
+	camel_data_wrapper_decode_to_stream (content, istream, NULL, NULL);
 	camel_stream_reset (istream, NULL);
 
 	ostream = camel_stream_mem_new ();
@@ -1971,7 +2017,7 @@ gpg_decrypt (CamelCipherContext *context,
 		goto fail;
 
 	while (!gpg_ctx_op_complete (gpg)) {
-		if (gpg_ctx_op_step (gpg, error) == -1) {
+		if (gpg_ctx_op_step (gpg, cancellable, error) == -1) {
 			gpg_ctx_op_cancel (gpg);
 			goto fail;
 		}
@@ -1995,14 +2041,16 @@ gpg_decrypt (CamelCipherContext *context,
 
 		/* Multipart encrypted - parse a full mime part */
 		rv = camel_data_wrapper_construct_from_stream (
-			CAMEL_DATA_WRAPPER (opart), ostream, error);
+			CAMEL_DATA_WRAPPER (opart),
+			ostream, NULL, error);
 
 		dw = camel_medium_get_content ((CamelMedium *)opart);
-		if (!camel_data_wrapper_decode_to_stream (dw, null, NULL)) {
+		if (!camel_data_wrapper_decode_to_stream (dw, null, cancellable, NULL)) {
 			/* nothing had been decoded from the stream, it doesn't
 			   contain any header, like Content-Type or such, thus
 			   write it as a message body */
-			rv = camel_data_wrapper_construct_from_stream (dw, ostream, error);
+			rv = camel_data_wrapper_construct_from_stream (
+				dw, ostream, NULL, error);
 		}
 
 		g_object_unref (null);
@@ -2010,7 +2058,8 @@ gpg_decrypt (CamelCipherContext *context,
 		/* Inline signed - raw data (may not be a mime part) */
 		CamelDataWrapper *dw;
 		dw = camel_data_wrapper_new ();
-		rv = camel_data_wrapper_construct_from_stream (dw, ostream, error);
+		rv = camel_data_wrapper_construct_from_stream (
+			dw, ostream, NULL, error);
 		camel_data_wrapper_set_mime_type(dw, "application/octet-stream");
 		camel_medium_set_content ((CamelMedium *)opart, dw);
 		g_object_unref (dw);
@@ -2052,6 +2101,7 @@ gpg_decrypt (CamelCipherContext *context,
 static gint
 gpg_import_keys (CamelCipherContext *context,
                  CamelStream *istream,
+                 GCancellable *cancellable,
                  GError **error)
 {
 	struct _GpgCtx *gpg;
@@ -2065,7 +2115,7 @@ gpg_import_keys (CamelCipherContext *context,
 		goto fail;
 
 	while (!gpg_ctx_op_complete (gpg)) {
-		if (gpg_ctx_op_step (gpg, error) == -1) {
+		if (gpg_ctx_op_step (gpg, cancellable, error) == -1) {
 			gpg_ctx_op_cancel (gpg);
 			goto fail;
 		}
@@ -2093,6 +2143,7 @@ static gint
 gpg_export_keys (CamelCipherContext *context,
                  GPtrArray *keys,
                  CamelStream *ostream,
+                 GCancellable *cancellable,
                  GError **error)
 {
 	struct _GpgCtx *gpg;
@@ -2112,7 +2163,7 @@ gpg_export_keys (CamelCipherContext *context,
 		goto fail;
 
 	while (!gpg_ctx_op_complete (gpg)) {
-		if (gpg_ctx_op_step (gpg, error) == -1) {
+		if (gpg_ctx_op_step (gpg, cancellable, error) == -1) {
 			gpg_ctx_op_cancel (gpg);
 			goto fail;
 		}
@@ -2136,43 +2187,6 @@ fail:
 	return res;
 }
 
-/* ********************************************************************** */
-
-static void
-gpg_context_set_property (GObject *object,
-                          guint property_id,
-                          const GValue *value,
-                          GParamSpec *pspec)
-{
-	switch (property_id) {
-		case PROP_ALWAYS_TRUST:
-			camel_gpg_context_set_always_trust (
-				CAMEL_GPG_CONTEXT (object),
-				g_value_get_boolean (value));
-			return;
-	}
-
-	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-}
-
-static void
-gpg_context_get_property (GObject *object,
-                          guint property_id,
-                          GValue *value,
-                          GParamSpec *pspec)
-{
-	switch (property_id) {
-		case PROP_ALWAYS_TRUST:
-			g_value_set_boolean (
-				value,
-				camel_gpg_context_get_always_trust (
-				CAMEL_GPG_CONTEXT (object)));
-			return;
-	}
-
-	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-}
-
 static void
 camel_gpg_context_class_init (CamelGpgContextClass *class)
 {
diff --git a/camel/camel-http-stream.c b/camel/camel-http-stream.c
index 452898b..8bac0f2 100644
--- a/camel/camel-http-stream.c
+++ b/camel/camel-http-stream.c
@@ -56,6 +56,7 @@ G_DEFINE_TYPE (CamelHttpStream, camel_http_stream, CAMEL_TYPE_STREAM)
 static CamelStream *
 http_connect (CamelHttpStream *http,
               CamelURL *url,
+              GCancellable *cancellable,
               GError **error)
 {
 	CamelTcpStream *tcp_stream;
@@ -91,7 +92,8 @@ http_connect (CamelHttpStream *http,
 
 	tcp_stream = CAMEL_TCP_STREAM (stream);
 
-	if (camel_tcp_stream_connect (tcp_stream, url->host, serv, 0, error) == -1) {
+	if (camel_tcp_stream_connect (
+		tcp_stream, url->host, serv, 0, cancellable, error) == -1) {
 		errsave = errno;
 		g_object_unref (stream);
 		errno = errsave;
@@ -125,6 +127,7 @@ http_disconnect (CamelHttpStream *http)
 
 static gint
 http_method_invoke (CamelHttpStream *http,
+                    GCancellable *cancellable,
                     GError **error)
 {
 	const gchar *method = NULL, *use_url;
@@ -202,8 +205,8 @@ http_method_invoke (CamelHttpStream *http,
 	}
 
 	/* end the headers */
-	if (camel_stream_write (http->raw, "\r\n", 2, error) == -1 ||
-		camel_stream_flush (http->raw, error) == -1) {
+	if (camel_stream_write (http->raw, "\r\n", 2, cancellable, error) == -1 ||
+		camel_stream_flush (http->raw, cancellable, error) == -1) {
 		http_disconnect (http);
 		return -1;
 	}
@@ -301,14 +304,15 @@ http_next_token (const guchar *in)
 
 static gint
 http_get_statuscode (CamelHttpStream *http,
+                     GCancellable *cancellable,
                      GError **error)
 {
 	const gchar *token;
 	gchar buffer[4096];
 
 	if (camel_stream_buffer_gets (
-		CAMEL_STREAM_BUFFER (http->read),
-		buffer, sizeof (buffer), error) <= 0)
+		CAMEL_STREAM_BUFFER (http->read), buffer,
+		sizeof (buffer), cancellable, error) <= 0)
 		return -1;
 
 	d(printf("HTTP Status: %s\n", buffer));
@@ -383,6 +387,7 @@ static gssize
 http_stream_read (CamelStream *stream,
                   gchar *buffer,
                   gsize n,
+                  GCancellable *cancellable,
                   GError **error)
 {
 	CamelHttpStream *http = CAMEL_HTTP_STREAM (stream);
@@ -404,15 +409,15 @@ http_stream_read (CamelStream *stream,
 	if (!http->raw) {
 		if (http_connect (
 			http, http->proxy ? http->proxy :
-			http->url, error) == NULL)
+			http->url, NULL, error) == NULL)
 			return -1;
 
-		if (http_method_invoke (http, error) == -1) {
+		if (http_method_invoke (http, cancellable, error) == -1) {
 			http_disconnect (http);
 			return -1;
 		}
 
-		if (http_get_statuscode (http, error) == -1) {
+		if (http_get_statuscode (http, cancellable, error) == -1) {
 			http_disconnect (http);
 			return -1;
 		}
@@ -486,6 +491,7 @@ static gssize
 http_stream_write (CamelStream *stream,
                    const gchar *buffer,
                    gsize n,
+                   GCancellable *cancellable,
                    GError **error)
 {
 	return -1;
@@ -493,24 +499,26 @@ http_stream_write (CamelStream *stream,
 
 static gint
 http_stream_flush (CamelStream *stream,
+                   GCancellable *cancellable,
                    GError **error)
 {
 	CamelHttpStream *http = (CamelHttpStream *) stream;
 
 	if (http->raw)
-		return camel_stream_flush (http->raw, error);
+		return camel_stream_flush (http->raw, cancellable, error);
 	else
 		return 0;
 }
 
 static gint
 http_stream_close (CamelStream *stream,
+                   GCancellable *cancellable,
                    GError **error)
 {
 	CamelHttpStream *http = (CamelHttpStream *) stream;
 
 	if (http->raw) {
-		if (camel_stream_close (http->raw, error) == -1)
+		if (camel_stream_close (http->raw, cancellable, error) == -1)
 			return -1;
 
 		http_disconnect (http);
@@ -591,7 +599,7 @@ camel_http_stream_get_content_type (CamelHttpStream *http_stream)
 	if (!http_stream->content_type && !http_stream->raw) {
 		CamelStream *stream = CAMEL_STREAM (http_stream);
 
-		if (http_stream_read (stream, NULL, 0, NULL) == -1)
+		if (http_stream_read (stream, NULL, 0, NULL, NULL) == -1)
 			return NULL;
 	}
 
diff --git a/camel/camel-index-control.c b/camel/camel-index-control.c
index cf9dd32..bc41315 100644
--- a/camel/camel-index-control.c
+++ b/camel/camel-index-control.c
@@ -189,7 +189,7 @@ do_perf (gint argc, gchar **argv)
 			CAMEL_MIME_FILTER_INDEX (filter_index), idn);
 		name = g_strdup_printf("%s/%s", path, d->d_name);
 		stream = camel_stream_fs_new_with_name (name, O_RDONLY, 0, NULL);
-		camel_stream_write_to_stream (stream, filter, NULL);
+		camel_stream_write_to_stream (stream, filter, NULL, NULL);
 		g_object_unref (stream);
 		g_free (name);
 
diff --git a/camel/camel-lock-client.c b/camel/camel-lock-client.c
index 8b4359e..538776c 100644
--- a/camel/camel-lock-client.c
+++ b/camel/camel-lock-client.c
@@ -225,7 +225,7 @@ again:
 				error, CAMEL_ERROR,
 				CAMEL_ERROR_GENERIC,
 				_("Could not lock '%s'"), path);
-			d(printf("locking failed !status = %d\n", msg->id));
+			d(printf("locking failed ! status = %d\n", msg->id));
 			break;
 		}
 	} else if (retry > 0) {
diff --git a/camel/camel-mime-filter-progress.c b/camel/camel-mime-filter-progress.c
index 6cdb3ce..30350f3 100644
--- a/camel/camel-mime-filter-progress.c
+++ b/camel/camel-mime-filter-progress.c
@@ -28,6 +28,7 @@
 #include <string.h>
 
 #include "camel-mime-filter-progress.h"
+#include "camel-operation.h"
 
 #define CAMEL_MIME_FILTER_PROGRESS_GET_PRIVATE(obj) \
 	(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -37,7 +38,7 @@
 #define w(x)
 
 struct _CamelMimeFilterProgressPrivate {
-	CamelOperation *operation;
+	GCancellable *cancellable;
 	gsize total;
 	gsize count;
 };
@@ -45,6 +46,22 @@ struct _CamelMimeFilterProgressPrivate {
 G_DEFINE_TYPE (CamelMimeFilterProgress, camel_mime_filter_progress, CAMEL_TYPE_MIME_FILTER)
 
 static void
+mime_filter_progress_dispose (GObject *object)
+{
+	CamelMimeFilterProgressPrivate *priv;
+
+	priv = CAMEL_MIME_FILTER_PROGRESS_GET_PRIVATE (object);
+
+	if (priv->cancellable != NULL) {
+		g_object_unref (priv->cancellable);
+		priv->cancellable = NULL;
+	}
+
+	/* Chain up to parent's dispose() method. */
+	G_OBJECT_CLASS (camel_mime_filter_progress_parent_class)->dispose (object);
+}
+
+static void
 mime_filter_progress_filter (CamelMimeFilter *mime_filter,
                              const gchar *in,
                              gsize len,
@@ -64,7 +81,7 @@ mime_filter_progress_filter (CamelMimeFilter *mime_filter,
 	else
 		percent = 100.0;
 
-	camel_operation_progress (priv->operation, (gint) percent);
+	camel_operation_progress (priv->cancellable, (gint) percent);
 
 	*outprespace = prespace;
 	*outlen = len;
@@ -98,10 +115,14 @@ mime_filter_progress_reset (CamelMimeFilter *mime_filter)
 static void
 camel_mime_filter_progress_class_init (CamelMimeFilterProgressClass *class)
 {
+	GObjectClass *object_class;
 	CamelMimeFilterClass *mime_filter_class;
 
 	g_type_class_add_private (class, sizeof (CamelMimeFilterProgressPrivate));
 
+	object_class = G_OBJECT_CLASS (class);
+	object_class->dispose = mime_filter_progress_dispose;
+
 	mime_filter_class = CAMEL_MIME_FILTER_CLASS (class);
 	mime_filter_class->filter = mime_filter_progress_filter;
 	mime_filter_class->complete = mime_filter_progress_complete;
@@ -116,29 +137,31 @@ camel_mime_filter_progress_init (CamelMimeFilterProgress *filter)
 
 /**
  * camel_mime_filter_progress_new:
- * @operation: a #CamelOperation
+ * @cancellable: a #CamelOperation cast as a #GCancellable
  * @total: total number of bytes to report progress on
  *
- * Create a new #CamelMimeFilterProgress object that will report
- * streaming progress.
+ * Create a new #CamelMimeFilterProgress object that will report streaming
+ * progress.  While the function will silently accept @cancellable being
+ * %NULL or a plain #GCancellable for convenience sake, no progress will be
+ * reported unless @cancellable is a #CamelOperation.
  *
  * Returns: a new #CamelMimeFilter object
  *
  * Since: 2.24
  **/
 CamelMimeFilter *
-camel_mime_filter_progress_new (CamelOperation *operation,
+camel_mime_filter_progress_new (GCancellable *cancellable,
                                 gsize total)
 {
 	CamelMimeFilter *filter;
 	CamelMimeFilterProgressPrivate *priv;
 
-	/* 'operation' can be NULL, then it means an active thread's operation */
-
 	filter = g_object_new (CAMEL_TYPE_MIME_FILTER_PROGRESS, NULL);
 	priv = CAMEL_MIME_FILTER_PROGRESS_GET_PRIVATE (filter);
 
-	priv->operation = operation;
+	if (CAMEL_IS_OPERATION (cancellable))
+		priv->cancellable = cancellable;
+
 	priv->total = total;
 
 	return filter;
diff --git a/camel/camel-mime-filter-progress.h b/camel/camel-mime-filter-progress.h
index 701aa94..437cd3f 100644
--- a/camel/camel-mime-filter-progress.h
+++ b/camel/camel-mime-filter-progress.h
@@ -27,7 +27,6 @@
 #ifndef CAMEL_MIME_FILTER_PROGRESS_H
 #define CAMEL_MIME_FILTER_PROGRESS_H
 
-#include <camel/camel-operation.h>
 #include <camel/camel-mime-filter.h>
 
 /* Standard GObject macros */
@@ -71,7 +70,7 @@ struct _CamelMimeFilterProgressClass {
 
 GType		camel_mime_filter_progress_get_type (void);
 CamelMimeFilter *
-		camel_mime_filter_progress_new	(CamelOperation *operation,
+		camel_mime_filter_progress_new	(GCancellable *cancellable,
 						 gsize total);
 
 G_END_DECLS
diff --git a/camel/camel-mime-filter-save.c b/camel/camel-mime-filter-save.c
index 3de1ef3..b7092f1 100644
--- a/camel/camel-mime-filter-save.c
+++ b/camel/camel-mime-filter-save.c
@@ -51,7 +51,7 @@ mime_filter_save_filter (CamelMimeFilter *mime_filter,
 	priv = CAMEL_MIME_FILTER_SAVE_GET_PRIVATE (mime_filter);
 
 	if (priv->stream != NULL)
-		camel_stream_write (priv->stream, in, len, NULL);
+		camel_stream_write (priv->stream, in, len, NULL, NULL);
 
 	*out = (gchar *) in;
 	*outlen = len;
diff --git a/camel/camel-mime-message.c b/camel/camel-mime-message.c
index a79774b..3aefe96 100644
--- a/camel/camel-mime-message.c
+++ b/camel/camel-mime-message.c
@@ -218,6 +218,7 @@ mime_message_finalize (GObject *object)
 static gssize
 mime_message_write_to_stream (CamelDataWrapper *data_wrapper,
                               CamelStream *stream,
+                              GCancellable *cancellable,
                               GError **error)
 {
 	CamelDataWrapperClass *data_wrapper_class;
@@ -244,8 +245,10 @@ mime_message_write_to_stream (CamelDataWrapper *data_wrapper,
 		camel_medium_set_header ((CamelMedium *)mm, "Mime-Version", "1.0");
 
 	/* Chain up to parent's write_to_stream() method. */
-	data_wrapper_class = CAMEL_DATA_WRAPPER_CLASS (camel_mime_message_parent_class);
-	return data_wrapper_class->write_to_stream (data_wrapper, stream, error);
+	data_wrapper_class = CAMEL_DATA_WRAPPER_CLASS (
+		camel_mime_message_parent_class);
+	return data_wrapper_class->write_to_stream (
+		data_wrapper, stream, cancellable, error);
 }
 
 static void
@@ -288,6 +291,7 @@ mime_message_remove_header (CamelMedium *medium,
 static gint
 mime_message_construct_from_parser (CamelMimePart *dw,
                                     CamelMimeParser *mp,
+                                    GCancellable *cancellable,
                                     GError **error)
 {
 	CamelMimePartClass *mime_part_class;
@@ -303,7 +307,8 @@ mime_message_construct_from_parser (CamelMimePart *dw,
 
 	/* let the mime-part construct the guts ... */
 	mime_part_class = CAMEL_MIME_PART_CLASS (camel_mime_message_parent_class);
-	ret = mime_part_class->construct_from_parser (dw, mp, error);
+	ret = mime_part_class->construct_from_parser (
+		dw, mp, cancellable, error);
 
 	if (ret == -1)
 		return -1;
@@ -905,7 +910,7 @@ find_best_encoding (CamelMimePart *part, CamelBestencRequired required, CamelBes
 	idb = camel_stream_filter_add (
 		CAMEL_STREAM_FILTER (filter), bestenc);
 	d(printf("writing to checking stream\n"));
-	camel_data_wrapper_decode_to_stream (content, filter, NULL);
+	camel_data_wrapper_decode_to_stream (content, filter, NULL, NULL);
 	camel_stream_filter_remove (CAMEL_STREAM_FILTER (filter), idb);
 	if (idc != -1) {
 		camel_stream_filter_remove (CAMEL_STREAM_FILTER (filter), idc);
@@ -949,7 +954,7 @@ find_best_encoding (CamelMimePart *part, CamelBestencRequired required, CamelBes
 
 			/* and write it to the new stream */
 			camel_data_wrapper_write_to_stream (
-				content, filter, NULL);
+				content, filter, NULL, NULL);
 
 			g_object_unref (charenc);
 		}
diff --git a/camel/camel-mime-parser.c b/camel/camel-mime-parser.c
index 81c8bfd..2756924 100644
--- a/camel/camel-mime-parser.c
+++ b/camel/camel-mime-parser.c
@@ -917,7 +917,7 @@ folder_read (struct _header_scan_state *s)
 	}
 	if (s->stream) {
 		len = camel_stream_read (
-			s->stream, s->inbuf+inoffset, SCAN_BUF-inoffset, NULL);
+			s->stream, s->inbuf+inoffset, SCAN_BUF-inoffset, NULL, NULL);
 	} else {
 		len = read (s->fd, s->inbuf+inoffset, SCAN_BUF-inoffset);
 	}
diff --git a/camel/camel-mime-part-utils.c b/camel/camel-mime-part-utils.c
index 8bb6165..1cef03a 100644
--- a/camel/camel-mime-part-utils.c
+++ b/camel/camel-mime-part-utils.c
@@ -57,6 +57,7 @@
 static gboolean
 simple_data_wrapper_construct_from_parser (CamelDataWrapper *dw,
                                            CamelMimeParser *mp,
+                                           GCancellable *cancellable,
                                            GError **error)
 {
 	gchar *buf;
@@ -77,7 +78,8 @@ simple_data_wrapper_construct_from_parser (CamelDataWrapper *dw,
 	d(printf("message part kept in memory!\n"));
 
 	mem = camel_stream_mem_new_with_byte_array (buffer);
-	retval = camel_data_wrapper_construct_from_stream (dw, mem, error);
+	retval = camel_data_wrapper_construct_from_stream (
+		dw, mem, cancellable, error);
 	g_object_unref (mem);
 
 	return (retval == 0);
@@ -91,6 +93,7 @@ simple_data_wrapper_construct_from_parser (CamelDataWrapper *dw,
 gboolean
 camel_mime_part_construct_content_from_parser (CamelMimePart *dw,
                                                CamelMimeParser *mp,
+                                               GCancellable *cancellable,
                                                GError **error)
 {
 	CamelDataWrapper *content = NULL;
@@ -114,14 +117,14 @@ camel_mime_part_construct_content_from_parser (CamelMimePart *dw,
 		} else {
 			content = camel_data_wrapper_new ();
 			success = simple_data_wrapper_construct_from_parser (
-				content, mp, error);
+				content, mp, cancellable, error);
 		}
 		break;
 	case CAMEL_MIME_PARSER_STATE_MESSAGE:
 		d(printf("Creating message part\n"));
 		content = (CamelDataWrapper *) camel_mime_message_new ();
 		success = (camel_mime_part_construct_from_parser (
-			(CamelMimePart *)content, mp, error) == 0);
+			(CamelMimePart *)content, mp, cancellable, error) == 0);
 		break;
 	case CAMEL_MIME_PARSER_STATE_MULTIPART:
 		d(printf("Creating multi-part\n"));
@@ -184,7 +187,7 @@ camel_mime_message_build_preview (CamelMimePart *msg,
 		    !camel_content_type_is (dw->mime_type, "text", "calendar")) {
 		CamelStream *mstream, *bstream;
 		mstream = camel_stream_mem_new ();
-		if (camel_data_wrapper_decode_to_stream (dw, mstream, NULL) > 0) {
+		if (camel_data_wrapper_decode_to_stream (dw, mstream, NULL, NULL) > 0) {
 			gchar *line = NULL;
 			GString *str = g_string_new (NULL);
 
@@ -192,7 +195,7 @@ camel_mime_message_build_preview (CamelMimePart *msg,
 			bstream = camel_stream_buffer_new (mstream, CAMEL_STREAM_BUFFER_READ|CAMEL_STREAM_BUFFER_BUFFER);
 
 			/* We should fetch just 200 unquoted lines. */
-			while ((line = camel_stream_buffer_read_line ((CamelStreamBuffer *)bstream, NULL)) && str->len < 200) {
+			while ((line = camel_stream_buffer_read_line ((CamelStreamBuffer *)bstream, NULL, NULL)) && str->len < 200) {
 				gchar *tmp = line;
 				if (!line)
 					continue;
diff --git a/camel/camel-mime-part-utils.h b/camel/camel-mime-part-utils.h
index 3c18aaa..e28ea59 100644
--- a/camel/camel-mime-part-utils.h
+++ b/camel/camel-mime-part-utils.h
@@ -38,6 +38,7 @@ G_BEGIN_DECLS
 gboolean	camel_mime_part_construct_content_from_parser
 						(CamelMimePart *mime_part,
 						 CamelMimeParser *mp,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_mime_message_build_preview (CamelMimePart *mime_part,
 						 CamelMessageInfo *info);
diff --git a/camel/camel-mime-part.c b/camel/camel-mime-part.c
index 90f9d23..a65dafa 100644
--- a/camel/camel-mime-part.c
+++ b/camel/camel-mime-part.c
@@ -93,34 +93,54 @@ static GHashTable *header_formatted_table;
 G_DEFINE_TYPE (CamelMimePart, camel_mime_part, CAMEL_TYPE_MEDIUM)
 
 static gssize
-write_raw (CamelStream *stream,
-           struct _camel_header_raw *h)
+write_header (CamelStream *stream,
+              const gchar *name,
+              const gchar *value,
+              GCancellable *cancellable,
+              GError **error)
 {
-	gchar *val = h->value;
+	GString *buffer;
+	gssize n_written;
 
-	return camel_stream_printf (
-		stream, "%s%s%s\n", h->name,
-		isspace(val[0]) ? ":" : ": ", val);
+	buffer = g_string_new (name);
+	g_string_append_c (buffer, ':');
+	if (!isspace (value[0]))
+		g_string_append_c (buffer, ' ');
+	g_string_append (buffer, value);
+	g_string_append_c (buffer, '\n');
+
+	n_written = camel_stream_write (
+		stream, buffer->str, buffer->len, cancellable, error);
+
+	g_string_free (buffer, TRUE);
+
+	return n_written;
 }
 
 static gssize
 write_references (CamelStream *stream,
-                  struct _camel_header_raw *h)
+                  const gchar *name,
+                  const gchar *value,
+                  GCancellable *cancellable,
+                  GError **error)
 {
-	gssize len, out, total;
-	gchar *value, *ids, *ide;
-
-	/* this is only approximate, based on the next >, this way it retains any content
-	   from the original which may not be properly formatted, etc.  It also doesn't handle
-	   the case where an individual messageid is too long, however thats a bad mail to
-	   start with ... */
-
-	value = h->value;
-	len = strlen (h->name)+1;
-	total = camel_stream_printf (
-		stream, "%s%s", h->name, isspace(value[0])?":":": ");
-	if (total == -1)
-		return -1;
+	GString *buffer;
+	const gchar *ids, *ide;
+	gssize n_written;
+	gsize len;
+
+	/* this is only approximate, based on the next >, this way it retains
+	 * any content from the original which may not be properly formatted,
+	 * etc.  It also doesn't handle the case where an individual messageid
+	 * is too long, however thats a bad mail to start with ... */
+
+	buffer = g_string_new (name);
+	g_string_append_c (buffer, ':');
+	if (!isspace (value[0]))
+		g_string_append_c (buffer, ' ');
+
+	len = buffer->len;
+
 	while (*value) {
 		ids = value;
 		ide = strchr (ids+1, '>');
@@ -129,22 +149,23 @@ write_references (CamelStream *stream,
 		else
 			ide = value = strlen (ids)+ids;
 
-		if (len>0 && len + (ide - ids) >= CAMEL_FOLD_SIZE) {
-			out = camel_stream_printf (stream, "\n\t");
-			if (out == -1)
-				return -1;
-			total += out;
+		if (len > 0 && len + (ide - ids) >= CAMEL_FOLD_SIZE) {
+			g_string_append_len (buffer, "\n\t", 2);
 			len = 0;
 		}
-		out = camel_stream_write (stream, ids, ide-ids, NULL);
-		if (out == -1)
-			return -1;
-		len += out;
-		total += out;
+
+		g_string_append_len (buffer, ids, ide - ids);
+		len += (ide - ids);
 	}
-	camel_stream_write (stream, "\n", 1, NULL);
 
-	return total;
+	g_string_append_c (buffer, '\n');
+
+	n_written = camel_stream_write (
+		stream, buffer->str, buffer->len, cancellable, error);
+
+	g_string_free (buffer, TRUE);
+
+	return n_written;
 }
 
 /* loads in a hash table the set of header names we */
@@ -188,22 +209,22 @@ init_header_name_table (void)
 		camel_strcase_hash, camel_strcase_equal);
 	g_hash_table_insert (
 		header_formatted_table,
-		(gpointer) "Content-Type", write_raw);
+		(gpointer) "Content-Type", write_header);
 	g_hash_table_insert (
 		header_formatted_table,
-		(gpointer) "Content-Disposition", write_raw);
+		(gpointer) "Content-Disposition", write_header);
 	g_hash_table_insert (
 		header_formatted_table,
-		(gpointer) "From", write_raw);
+		(gpointer) "From", write_header);
 	g_hash_table_insert (
 		header_formatted_table,
-		(gpointer) "Reply-To", write_raw);
+		(gpointer) "Reply-To", write_header);
 	g_hash_table_insert (
 		header_formatted_table,
-		(gpointer) "Message-ID", write_raw);
+		(gpointer) "Message-ID", write_header);
 	g_hash_table_insert (
 		header_formatted_table,
-		(gpointer) "In-Reply-To", write_raw);
+		(gpointer) "In-Reply-To", write_header);
 	g_hash_table_insert (
 		header_formatted_table,
 		(gpointer) "References", write_references);
@@ -478,6 +499,7 @@ mime_part_set_content (CamelMedium *medium,
 static gssize
 mime_part_write_to_stream (CamelDataWrapper *dw,
                            CamelStream *stream,
+                           GCancellable *cancellable,
                            GError **error)
 {
 	CamelMimePart *mp = CAMEL_MIME_PART (dw);
@@ -496,7 +518,11 @@ mime_part_write_to_stream (CamelDataWrapper *dw,
 	if (mp->headers) {
 		struct _camel_header_raw *h = mp->headers;
 		gchar *val;
-		gssize (*writefn)(CamelStream *stream, struct _camel_header_raw *);
+		gssize		(*writefn)	(CamelStream *stream,
+						 const gchar *name,
+						 const gchar *value,
+						 GCancellable *cancellable,
+						 GError **error);
 
 		/* fold/write the headers.   But dont fold headers that are already formatted
 		   (e.g. ones with parameter-lists, that we know about, and have created) */
@@ -507,24 +533,23 @@ mime_part_write_to_stream (CamelDataWrapper *dw,
 				count = 0;
 			} else if ((writefn = g_hash_table_lookup (header_formatted_table, h->name)) == NULL) {
 				val = camel_header_fold (val, strlen (h->name));
-				count = camel_stream_printf(stream, "%s%s%s\n", h->name, isspace(val[0]) ? ":" : ": ", val);
+				count = write_header (
+					stream, h->name, val,
+					cancellable, error);
 				g_free (val);
 			} else {
-				count = writefn (stream, h);
+				count = writefn (
+					stream, h->name, h->value,
+					cancellable, error);
 			}
-			if (count == -1) {
-				g_set_error (
-					error, G_IO_ERROR,
-					g_io_error_from_errno (errno),
-					"%s", g_strerror (errno));
+			if (count == -1)
 				return -1;
-			}
 			total += count;
 			h = h->next;
 		}
 	}
 
-	count = camel_stream_write (stream, "\n", 1, error);
+	count = camel_stream_write (stream, "\n", 1, cancellable, error);
 	if (count == -1)
 		return -1;
 	total += count;
@@ -615,14 +640,14 @@ mime_part_write_to_stream (CamelDataWrapper *dw,
 
 		if (reencode)
 			count = camel_data_wrapper_decode_to_stream (
-				content, stream, error);
+				content, stream, cancellable, error);
 		else
 			count = camel_data_wrapper_write_to_stream (
-				content, stream, error);
+				content, stream, cancellable, error);
 
 		if (filter_stream) {
 			errnosav = errno;
-			camel_stream_flush (stream, NULL);
+			camel_stream_flush (stream, NULL, NULL);
 			g_object_unref (filter_stream);
 			errno = errnosav;
 		}
@@ -633,7 +658,8 @@ mime_part_write_to_stream (CamelDataWrapper *dw,
 		total += count;
 
 		if (reencode && mp->priv->encoding == CAMEL_TRANSFER_ENCODING_UUENCODE) {
-			count = camel_stream_write (ostream, "end\n", 4, error);
+			count = camel_stream_write (
+				ostream, "end\n", 4, cancellable, error);
 			if (count == -1)
 				return -1;
 			total += count;
@@ -648,6 +674,7 @@ mime_part_write_to_stream (CamelDataWrapper *dw,
 static gint
 mime_part_construct_from_stream (CamelDataWrapper *dw,
                                  CamelStream *s,
+                                 GCancellable *cancellable,
                                  GError **error)
 {
 	CamelMimeParser *mp;
@@ -660,7 +687,7 @@ mime_part_construct_from_stream (CamelDataWrapper *dw,
 		ret = -1;
 	} else {
 		ret = camel_mime_part_construct_from_parser (
-			CAMEL_MIME_PART (dw), mp, error);
+			CAMEL_MIME_PART (dw), mp, cancellable, error);
 	}
 	g_object_unref (mp);
 	return ret;
@@ -669,6 +696,7 @@ mime_part_construct_from_stream (CamelDataWrapper *dw,
 static gint
 mime_part_construct_from_parser (CamelMimePart *mime_part,
                                  CamelMimeParser *mp,
+                                 GCancellable *cancellable,
                                  GError **error)
 {
 	CamelDataWrapper *dw = (CamelDataWrapper *) mime_part;
@@ -708,7 +736,7 @@ mime_part_construct_from_parser (CamelMimePart *mime_part,
 		}
 
 		success = camel_mime_part_construct_content_from_parser (
-			mime_part, mp, error);
+			mime_part, mp, cancellable, error);
 		retval = success ? 0 : -1;
 		break;
 	default:
@@ -1248,6 +1276,8 @@ camel_mime_part_get_content_type (CamelMimePart *mime_part)
  * camel_mime_part_construct_from_parser:
  * @mime_part: a #CamelMimePart object
  * @parser: a #CamelMimeParser object
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
  *
  * Constructs a MIME part from a parser.
  *
@@ -1256,6 +1286,7 @@ camel_mime_part_get_content_type (CamelMimePart *mime_part)
 gint
 camel_mime_part_construct_from_parser (CamelMimePart *mime_part,
                                        CamelMimeParser *mp,
+                                       GCancellable *cancellable,
                                        GError **error)
 {
 	CamelMimePartClass *class;
@@ -1267,8 +1298,10 @@ camel_mime_part_construct_from_parser (CamelMimePart *mime_part,
 	class = CAMEL_MIME_PART_GET_CLASS (mime_part);
 	g_return_val_if_fail (class->construct_from_parser != NULL, -1);
 
-	retval = class->construct_from_parser (mime_part, mp, error);
-	CAMEL_CHECK_GERROR (mime_part, construct_from_parser, retval == 0, error);
+	retval = class->construct_from_parser (
+		mime_part, mp, cancellable, error);
+	CAMEL_CHECK_GERROR (
+		mime_part, construct_from_parser, retval == 0, error);
 
 	return retval;
 }
@@ -1312,7 +1345,8 @@ camel_mime_part_set_content (CamelMimePart *mime_part,
 		dw = camel_data_wrapper_new ();
 		camel_data_wrapper_set_mime_type (dw, type);
 		stream = camel_stream_mem_new_with_buffer (data, length);
-		camel_data_wrapper_construct_from_stream (dw, stream, NULL);
+		camel_data_wrapper_construct_from_stream (
+			dw, stream, NULL, NULL);
 		g_object_unref (stream);
 		camel_medium_set_content (medium, dw);
 		g_object_unref (dw);
@@ -1333,7 +1367,7 @@ camel_mime_part_set_content (CamelMimePart *mime_part,
 gsize
 camel_mime_part_get_content_size (CamelMimePart *mime_part)
 {
-	CamelStreamNull *null;
+	CamelStream *null;
 	CamelDataWrapper *dw;
 	gsize size;
 
@@ -1341,9 +1375,9 @@ camel_mime_part_get_content_size (CamelMimePart *mime_part)
 
 	dw = camel_medium_get_content (CAMEL_MEDIUM (mime_part));
 
-	null = (CamelStreamNull *) camel_stream_null_new ();
-	camel_data_wrapper_decode_to_stream (dw, (CamelStream *) null, NULL);
-	size = null->written;
+	null = camel_stream_null_new ();
+	camel_data_wrapper_decode_to_stream (dw, null, NULL, NULL);
+	size = CAMEL_STREAM_NULL (null)->written;
 
 	g_object_unref (null);
 
diff --git a/camel/camel-mime-part.h b/camel/camel-mime-part.h
index 216a780..6259d19 100644
--- a/camel/camel-mime-part.h
+++ b/camel/camel-mime-part.h
@@ -69,53 +69,70 @@ struct _CamelMimePart {
 struct _CamelMimePartClass {
 	CamelMediumClass parent_class;
 
-	gint		(*construct_from_parser)(CamelMimePart *mime_part,
+	gint	(*construct_from_parser)	(CamelMimePart *mime_part,
 						 CamelMimeParser *parser,
+						 GCancellable *cancellable,
 						 GError **error);
 };
 
-GType camel_mime_part_get_type (void);
-
-/* public methods */
-CamelMimePart *  camel_mime_part_new                    (void);
-
-void		 camel_mime_part_set_description	(CamelMimePart *mime_part, const gchar *description);
-const     gchar  *camel_mime_part_get_description	(CamelMimePart *mime_part);
-
-void		 camel_mime_part_set_disposition	(CamelMimePart *mime_part, const gchar *disposition);
-const     gchar  *camel_mime_part_get_disposition	(CamelMimePart *mime_part);
-const CamelContentDisposition *camel_mime_part_get_content_disposition (CamelMimePart *mime_part);
-
-void		 camel_mime_part_set_filename		(CamelMimePart *mime_part, const gchar *filename);
-const	  gchar  *camel_mime_part_get_filename		(CamelMimePart *mime_part);
-
-void             camel_mime_part_set_content_id		(CamelMimePart *mime_part, const gchar *contentid);
-const	  gchar  *camel_mime_part_get_content_id		(CamelMimePart *mime_part);
-
-void		 camel_mime_part_set_content_md5	(CamelMimePart *mime_part, const gchar *md5sum);
-const	  gchar  *camel_mime_part_get_content_md5	(CamelMimePart *mime_part);
-
-void		 camel_mime_part_set_content_location	(CamelMimePart *mime_part, const gchar *location);
-const	  gchar  *camel_mime_part_get_content_location	(CamelMimePart *mime_part);
-
-void		 camel_mime_part_set_encoding		(CamelMimePart *mime_part, CamelTransferEncoding encoding);
-CamelTransferEncoding camel_mime_part_get_encoding	(CamelMimePart *mime_part);
-
-void		 camel_mime_part_set_content_languages	(CamelMimePart *mime_part, GList *content_languages);
-const	  GList *camel_mime_part_get_content_languages	(CamelMimePart *mime_part);
+GType		camel_mime_part_get_type	(void);
+CamelMimePart *	camel_mime_part_new		(void);
+void		camel_mime_part_set_description	(CamelMimePart *mime_part,
+						 const gchar *description);
+const gchar *	camel_mime_part_get_description	(CamelMimePart *mime_part);
+void		camel_mime_part_set_disposition	(CamelMimePart *mime_part,
+						 const gchar *disposition);
+const gchar *	camel_mime_part_get_disposition	(CamelMimePart *mime_part);
+const CamelContentDisposition *
+		camel_mime_part_get_content_disposition
+						(CamelMimePart *mime_part);
+void		camel_mime_part_set_filename	(CamelMimePart *mime_part,
+						 const gchar *filename);
+const gchar *	camel_mime_part_get_filename	(CamelMimePart *mime_part);
+void		camel_mime_part_set_content_id	(CamelMimePart *mime_part,
+						 const gchar *contentid);
+const gchar *	camel_mime_part_get_content_id	(CamelMimePart *mime_part);
+void		camel_mime_part_set_content_md5	(CamelMimePart *mime_part,
+						 const gchar *md5sum);
+const gchar *	camel_mime_part_get_content_md5	(CamelMimePart *mime_part);
+void		camel_mime_part_set_content_location
+						(CamelMimePart *mime_part,
+						 const gchar *location);
+const gchar *	camel_mime_part_get_content_location
+						(CamelMimePart *mime_part);
+void		camel_mime_part_set_encoding	(CamelMimePart *mime_part,
+						 CamelTransferEncoding encoding);
+CamelTransferEncoding
+		camel_mime_part_get_encoding	(CamelMimePart *mime_part);
+void		camel_mime_part_set_content_languages
+						(CamelMimePart *mime_part,
+						 GList *content_languages);
+const GList *	camel_mime_part_get_content_languages
+						(CamelMimePart *mime_part);
 
 /* FIXME: what about content-type parameters?   what about major/minor parts? */
-void               camel_mime_part_set_content_type	(CamelMimePart *mime_part, const gchar *content_type);
-CamelContentType  *camel_mime_part_get_content_type	(CamelMimePart *mime_part);
+void		camel_mime_part_set_content_type
+						(CamelMimePart *mime_part,
+						 const gchar *content_type);
+CamelContentType *
+		camel_mime_part_get_content_type
+						(CamelMimePart *mime_part);
 
 /* construction */
-gint		camel_mime_part_construct_from_parser  (CamelMimePart *mime_part, CamelMimeParser *parser, GError **error);
+gint		camel_mime_part_construct_from_parser
+						(CamelMimePart *mime_part,
+						 CamelMimeParser *parser,
+						 GCancellable *cancellable,
+						 GError **error);
 
 /* utility functions */
-void	camel_mime_part_set_content	       (CamelMimePart *mime_part,
-							const gchar *data, gint length, const gchar *type);
+void		camel_mime_part_set_content	(CamelMimePart *mime_part,
+						 const gchar *data,
+						 gint length,
+						 const gchar *type);
 
-gsize          camel_mime_part_get_content_size       (CamelMimePart *mime_part);
+gsize		camel_mime_part_get_content_size
+						(CamelMimePart *mime_part);
 
 G_END_DECLS
 
diff --git a/camel/camel-mime-utils.c b/camel/camel-mime-utils.c
index 8798c58..cf620a6 100644
--- a/camel/camel-mime-utils.c
+++ b/camel/camel-mime-utils.c
@@ -4359,7 +4359,8 @@ camel_header_msgid_generate (void)
 		retval = gethostname (host, sizeof (host));
 		if (retval == 0 && *host) {
 			hints.ai_flags = AI_CANONNAME;
-			ai = camel_getaddrinfo (host, NULL, &hints, NULL);
+			ai = camel_getaddrinfo (
+				host, NULL, &hints, NULL, NULL);
 			if (ai && ai->ai_canonname)
 				name = ai->ai_canonname;
 			else
diff --git a/camel/camel-multipart-signed.c b/camel/camel-multipart-signed.c
index e52ba08..f61c08c 100644
--- a/camel/camel-multipart-signed.c
+++ b/camel/camel-multipart-signed.c
@@ -256,6 +256,7 @@ multipart_signed_set_mime_type_field (CamelDataWrapper *data_wrapper,
 static gssize
 multipart_signed_write_to_stream (CamelDataWrapper *data_wrapper,
                                   CamelStream *stream,
+                                  GCancellable *cancellable,
                                   GError **error)
 {
 	CamelMultipartSigned *mps = (CamelMultipartSigned *)data_wrapper;
@@ -275,7 +276,7 @@ multipart_signed_write_to_stream (CamelDataWrapper *data_wrapper,
 	if (data_wrapper->stream) {
 		camel_stream_reset (data_wrapper->stream, NULL);
 		return camel_stream_write_to_stream (
-			data_wrapper->stream, stream, error);
+			data_wrapper->stream, stream, cancellable, error);
 	}
 
 	/* 3 */
@@ -297,7 +298,8 @@ multipart_signed_write_to_stream (CamelDataWrapper *data_wrapper,
 	/* 2 */
 	boundary = camel_multipart_get_boundary (mp);
 	if (mp->preface) {
-		count = camel_stream_write_string (stream, mp->preface, error);
+		count = camel_stream_write_string (
+			stream, mp->preface, cancellable, error);
 		if (count == -1)
 			return -1;
 		total += count;
@@ -311,7 +313,8 @@ multipart_signed_write_to_stream (CamelDataWrapper *data_wrapper,
 
 	/* output content part */
 	camel_stream_reset (mps->contentraw, NULL);
-	count = camel_stream_write_to_stream (mps->contentraw, stream, error);
+	count = camel_stream_write_to_stream (
+		mps->contentraw, stream, cancellable, error);
 	if (count == -1)
 		return -1;
 	total += count;
@@ -324,7 +327,8 @@ multipart_signed_write_to_stream (CamelDataWrapper *data_wrapper,
 
 	/* signature */
 	count = camel_data_wrapper_write_to_stream (
-		CAMEL_DATA_WRAPPER (mps->signature), stream, error);
+		CAMEL_DATA_WRAPPER (mps->signature),
+		stream, cancellable, error);
 	if (count == -1)
 		return -1;
 	total += count;
@@ -337,7 +341,8 @@ multipart_signed_write_to_stream (CamelDataWrapper *data_wrapper,
 
 	/* and finally the postface */
 	if (mp->postface) {
-		count = camel_stream_write_string (stream, mp->postface, error);
+		count = camel_stream_write_string (
+			stream, mp->postface, cancellable, error);
 		if (count == -1)
 			return -1;
 		total += count;
@@ -357,12 +362,14 @@ file_error:
 static gint
 multipart_signed_construct_from_stream (CamelDataWrapper *data_wrapper,
                                         CamelStream *stream,
+                                        GCancellable *cancellable,
                                         GError **error)
 {
 	CamelMultipartSigned *mps = (CamelMultipartSigned *)data_wrapper;
 	CamelStream *mem = camel_stream_mem_new ();
 
-	if (camel_stream_write_to_stream (stream, mem, error) == -1)
+	if (camel_stream_write_to_stream (
+		stream, mem, cancellable, error) == -1)
 		return -1;
 
 	multipart_signed_set_stream (mps, mem);
@@ -430,7 +437,7 @@ multipart_signed_get_part (CamelMultipart *multipart,
 		camel_stream_reset (stream, NULL);
 		mps->content = camel_mime_part_new ();
 		camel_data_wrapper_construct_from_stream (
-			CAMEL_DATA_WRAPPER (mps->content), stream, NULL);
+			CAMEL_DATA_WRAPPER (mps->content), stream, NULL, NULL);
 		g_object_unref (stream);
 		return mps->content;
 	case CAMEL_MULTIPART_SIGNED_SIGNATURE:
@@ -447,7 +454,8 @@ multipart_signed_get_part (CamelMultipart *multipart,
 		camel_stream_reset (stream, NULL);
 		mps->signature = camel_mime_part_new ();
 		camel_data_wrapper_construct_from_stream (
-			CAMEL_DATA_WRAPPER (mps->signature), stream, NULL);
+			CAMEL_DATA_WRAPPER (mps->signature),
+			stream, NULL, NULL);
 		g_object_unref (stream);
 		return mps->signature;
 	default:
@@ -499,7 +507,7 @@ multipart_signed_construct_from_parser (CamelMultipart *multipart,
 
 	stream = camel_stream_mem_new ();
 	while (camel_mime_parser_step (mp, &buf, &len) != CAMEL_MIME_PARSER_STATE_BODY_END)
-		camel_stream_write (stream, buf, len, NULL);
+		camel_stream_write (stream, buf, len, NULL, NULL);
 
 	multipart_signed_set_stream (mps, stream);
 
diff --git a/camel/camel-multipart.c b/camel/camel-multipart.c
index 1f2ae22..cae7ea1 100644
--- a/camel/camel-multipart.c
+++ b/camel/camel-multipart.c
@@ -68,6 +68,7 @@ multipart_finalize (GObject *object)
 static gssize
 multipart_write_to_stream (CamelDataWrapper *data_wrapper,
                            CamelStream *stream,
+                           GCancellable *cancellable,
                            GError **error)
 {
 	CamelMultipart *multipart = CAMEL_MULTIPART (data_wrapper);
@@ -89,7 +90,7 @@ multipart_write_to_stream (CamelDataWrapper *data_wrapper,
 	 */
 	if (multipart->preface) {
 		count = camel_stream_write_string (
-			stream, multipart->preface, error);
+			stream, multipart->preface, cancellable, error);
 		if (count == -1)
 			return -1;
 		total += count;
@@ -108,7 +109,8 @@ multipart_write_to_stream (CamelDataWrapper *data_wrapper,
 		total += count;
 
 		count = camel_data_wrapper_write_to_stream (
-			CAMEL_DATA_WRAPPER (node->data), stream, error);
+			CAMEL_DATA_WRAPPER (node->data),
+			stream, cancellable, error);
 		if (count == -1)
 			return -1;
 		total += count;
@@ -125,7 +127,7 @@ multipart_write_to_stream (CamelDataWrapper *data_wrapper,
 	/* and finally the postface */
 	if (multipart->postface) {
 		count = camel_stream_write_string (
-			stream, multipart->postface, error);
+			stream, multipart->postface, cancellable, error);
 		if (count == -1)
 			return -1;
 		total += count;
@@ -310,7 +312,8 @@ multipart_construct_from_parser (CamelMultipart *multipart,
 	while (camel_mime_parser_step (mp, &buf, &len) != CAMEL_MIME_PARSER_STATE_MULTIPART_END) {
 		camel_mime_parser_unstep (mp);
 		bodypart = camel_mime_part_new ();
-		camel_mime_part_construct_from_parser (bodypart, mp, NULL);
+		camel_mime_part_construct_from_parser (
+			bodypart, mp, NULL, NULL);
 		camel_multipart_add_part (multipart, bodypart);
 		g_object_unref (bodypart);
 	}
diff --git a/camel/camel-net-utils.c b/camel/camel-net-utils.c
index 02ab503..6769285 100644
--- a/camel/camel-net-utils.c
+++ b/camel/camel-net-utils.c
@@ -449,13 +449,14 @@ static gint
 cs_waitinfo (gpointer (worker)(gpointer),
              struct _addrinfo_msg *msg,
              const gchar *errmsg,
+             GCancellable *cancellable,
              GError **error)
 {
 	CamelMsgPort *reply_port;
 	GThread *thread;
 	gint cancel_fd, cancel = 0, fd;
 
-	cancel_fd = camel_operation_cancel_fd (NULL);
+	cancel_fd = g_cancellable_get_fd (cancellable);
 	if (cancel_fd == -1) {
 		worker (msg);
 		return 0;
@@ -533,6 +534,8 @@ cs_waitinfo (gpointer (worker)(gpointer),
 	}
 	camel_msgport_destroy (reply_port);
 
+	g_cancellable_release_fd (cancellable);
+
 	return cancel;
 }
 
@@ -675,6 +678,7 @@ struct addrinfo *
 camel_getaddrinfo (const gchar *name,
                    const gchar *service,
                    const struct addrinfo *hints,
+                   GCancellable *cancellable,
                    GError **error)
 {
 	struct _addrinfo_msg *msg;
@@ -684,15 +688,11 @@ camel_getaddrinfo (const gchar *name,
 #endif
 	g_return_val_if_fail (name != NULL, NULL);
 
-	if (camel_operation_cancel_check (NULL)) {
-		g_set_error (
-			error, G_IO_ERROR,
-			G_IO_ERROR_CANCELLED,
-			_("Cancelled"));
+	if (g_cancellable_set_error_if_cancelled (cancellable, error))
 		return NULL;
-	}
 
-	camel_operation_start_transient(NULL, _("Resolving: %s"), name);
+	camel_operation_start_transient (
+		cancellable, _("Resolving: %s"), name);
 
 	/* force ipv4 addresses only */
 #ifndef ENABLE_IPv6
@@ -714,7 +714,10 @@ camel_getaddrinfo (const gchar *name,
 	msg->hostbuflen = 1024;
 	msg->hostbufmem = g_malloc (msg->hostbuflen);
 #endif
-	if (cs_waitinfo(cs_getaddrinfo, msg, _("Host lookup failed"), error) == 0) {
+	if (cs_waitinfo (
+		cs_getaddrinfo, msg, _("Host lookup failed"),
+		cancellable, error) == 0) {
+
 		if (msg->result != 0) {
 			g_set_error (
 				error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
@@ -725,7 +728,8 @@ camel_getaddrinfo (const gchar *name,
 		res = NULL;
 
 	cs_freeinfo (msg);
-	camel_operation_end (NULL);
+
+	camel_operation_end (cancellable);
 
 	return res;
 }
@@ -828,20 +832,17 @@ camel_getnameinfo (const struct sockaddr *sa,
                    gchar **host,
                    gchar **serv,
                    gint flags,
+                   GCancellable *cancellable,
                    GError **error)
 {
 	struct _addrinfo_msg *msg;
 	gint result;
 
-	if (camel_operation_cancel_check (NULL)) {
-		g_set_error (
-			error, G_IO_ERROR,
-			G_IO_ERROR_CANCELLED,
-			_("Cancelled"));
+	if (g_cancellable_set_error_if_cancelled (cancellable, error))
 		return -1;
-	}
 
-	camel_operation_start_transient(NULL, _("Resolving address"));
+	camel_operation_start_transient (
+		cancellable, _("Resolving address"));
 
 	msg = g_malloc0 (sizeof (*msg));
 	msg->addr = sa;
@@ -861,7 +862,9 @@ camel_getnameinfo (const struct sockaddr *sa,
 	msg->hostbuflen = 1024;
 	msg->hostbufmem = g_malloc (msg->hostbuflen);
 #endif
-	cs_waitinfo(cs_getnameinfo, msg, _("Name lookup failed"), error);
+	cs_waitinfo (
+		cs_getnameinfo, msg, _("Name lookup failed"),
+		cancellable, error);
 
 	if ((result = msg->result) != 0)
 		g_set_error (
@@ -875,7 +878,8 @@ camel_getnameinfo (const struct sockaddr *sa,
 	}
 
 	cs_freeinfo (msg);
-	camel_operation_end (NULL);
+
+	camel_operation_end (cancellable);
 
 	return result;
 }
diff --git a/camel/camel-net-utils.h b/camel/camel-net-utils.h
index 0a36677..655e1b4 100644
--- a/camel/camel-net-utils.h
+++ b/camel/camel-net-utils.h
@@ -27,6 +27,7 @@
 #ifndef CAMEL_NET_UTILS_H
 #define CAMEL_NET_UTILS_H
 
+#include <gio/gio.h>
 #include <sys/types.h>
 
 #ifndef _WIN32
@@ -88,11 +89,20 @@ struct addrinfo {
 #endif
 #endif
 
-struct addrinfo *camel_getaddrinfo (const gchar *name, const gchar *service,
-				   const struct addrinfo *hints, GError **error);
-void camel_freeaddrinfo (struct addrinfo *host);
-gint camel_getnameinfo (const struct sockaddr *sa, socklen_t salen, gchar **host, gchar **serv,
-		      gint flags, GError **error);
+struct addrinfo *
+		camel_getaddrinfo		(const gchar *name,
+						 const gchar *service,
+						 const struct addrinfo *hints,
+						 GCancellable *cancellable,
+						 GError **error);
+void		camel_freeaddrinfo		(struct addrinfo *host);
+gint		camel_getnameinfo		(const struct sockaddr *sa,
+						 socklen_t salen,
+						 gchar **host,
+						 gchar **serv,
+						 gint flags,
+						 GCancellable *cancellable,
+						 GError **error);
 
 G_END_DECLS
 
diff --git a/camel/camel-offline-folder.c b/camel/camel-offline-folder.c
index c643810..af31836 100644
--- a/camel/camel-offline-folder.c
+++ b/camel/camel-offline-folder.c
@@ -63,20 +63,28 @@ offline_downsync_sync (CamelSession *session, CamelSessionThreadMsg *mm)
 	struct _offline_downsync_msg *m = (struct _offline_downsync_msg *) mm;
 	gint i;
 
-	camel_operation_start (NULL, _("Downloading new messages for offline mode"));
+	camel_operation_start (
+		mm->cancellable,
+		_("Downloading new messages for offline mode"));
 
 	if (m->changes) {
 		for (i = 0; i < m->changes->uid_added->len; i++) {
 			gint pc = i * 100 / m->changes->uid_added->len;
 
-			camel_operation_progress (NULL, pc);
-			camel_folder_sync_message (m->folder, m->changes->uid_added->pdata[i], &mm->error);
+			camel_operation_progress (mm->cancellable, pc);
+			/* FIXME Pass a GCancellable */
+			camel_folder_sync_message (
+				m->folder, m->changes->uid_added->pdata[i],
+				NULL, &mm->error);
 		}
 	} else {
-		camel_offline_folder_downsync ((CamelOfflineFolder *) m->folder, "(match-all)", &mm->error);
+		/* FIXME Pass a GCancellable */
+		camel_offline_folder_downsync (
+			(CamelOfflineFolder *) m->folder,
+			"(match-all)", NULL, &mm->error);
 	}
 
-	camel_operation_end (NULL);
+	camel_operation_end (mm->cancellable);
 }
 
 static void
@@ -159,6 +167,7 @@ offline_folder_get_property (GObject *object,
 static gboolean
 offline_folder_downsync (CamelOfflineFolder *offline,
                          const gchar *expression,
+                         GCancellable *cancellable,
                          GError **error)
 {
 	CamelFolder *folder = (CamelFolder *) offline;
@@ -166,7 +175,7 @@ offline_folder_downsync (CamelOfflineFolder *offline,
 	gint i;
 
 	camel_operation_start (
-		NULL, _("Syncing messages in folder '%s' to disk"),
+		cancellable, _("Syncing messages in folder '%s' to disk"),
 		camel_folder_get_full_name (folder));
 
 	if (expression)
@@ -188,16 +197,17 @@ offline_folder_downsync (CamelOfflineFolder *offline,
 		goto done;
 
 	for (i = 0; i < uncached_uids->len; i++) {
-		gint pc = i * 100 / uncached_uids->len;
-		camel_folder_sync_message (folder, uncached_uids->pdata[i], NULL);
-		camel_operation_progress (NULL, pc);
+		camel_folder_sync_message (
+			folder, uncached_uids->pdata[i], cancellable, NULL);
+		camel_operation_progress (
+			cancellable, i * 100 / uncached_uids->len);
 	}
 
 done:
 	if (uncached_uids)
 		camel_folder_free_uids (folder, uncached_uids);
 
-	camel_operation_end (NULL);
+	camel_operation_end (cancellable);
 
 	return TRUE;
 }
@@ -272,7 +282,9 @@ camel_offline_folder_set_offline_sync (CamelOfflineFolder *offline_folder,
 /**
  * camel_offline_folder_downsync:
  * @offline: a #CamelOfflineFolder object
- * @expression: search expression describing which set of messages to downsync (%NULL for all)
+ * @expression: search expression describing which set of messages
+ *              to downsync (%NULL for all)
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Syncs messages in @offline described by the search @expression to
@@ -283,6 +295,7 @@ camel_offline_folder_set_offline_sync (CamelOfflineFolder *offline_folder,
 gboolean
 camel_offline_folder_downsync (CamelOfflineFolder *offline,
                                const gchar *expression,
+                               GCancellable *cancellable,
                                GError **error)
 {
 	CamelOfflineFolderClass *class;
@@ -293,7 +306,7 @@ camel_offline_folder_downsync (CamelOfflineFolder *offline,
 	class = CAMEL_OFFLINE_FOLDER_GET_CLASS (offline);
 	g_return_val_if_fail (class->downsync != NULL, FALSE);
 
-	success = class->downsync (offline, expression, error);
+	success = class->downsync (offline, expression, cancellable, error);
 	CAMEL_CHECK_GERROR (offline, downsync, success, error);
 
 	return success;
diff --git a/camel/camel-offline-folder.h b/camel/camel-offline-folder.h
index 9032abd..b8868db 100644
--- a/camel/camel-offline-folder.h
+++ b/camel/camel-offline-folder.h
@@ -64,6 +64,7 @@ struct _CamelOfflineFolderClass {
 
 	gboolean	(*downsync)		(CamelOfflineFolder *folder,
 						 const gchar *expression,
+						 GCancellable *cancellable,
 						 GError **error);
 };
 
@@ -75,6 +76,7 @@ void		camel_offline_folder_set_offline_sync
 						 gboolean offline_sync);
 gboolean	camel_offline_folder_downsync	(CamelOfflineFolder *offline,
 						 const gchar *expression,
+						 GCancellable *cancellable,
 						 GError **error);
 
 G_END_DECLS
diff --git a/camel/camel-offline-journal.c b/camel/camel-offline-journal.c
index 76006cb..f76bc6a 100644
--- a/camel/camel-offline-journal.c
+++ b/camel/camel-offline-journal.c
@@ -179,6 +179,7 @@ camel_offline_journal_write (CamelOfflineJournal *journal,
 /**
  * camel_offline_journal_replay:
  * @journal: a #CamelOfflineJournal object
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Replay all entries in the journal.
@@ -187,6 +188,7 @@ camel_offline_journal_write (CamelOfflineJournal *journal,
  **/
 gint
 camel_offline_journal_replay (CamelOfflineJournal *journal,
+                              GCancellable *cancellable,
                               GError **error)
 {
 	CamelDListNode *entry, *next;
@@ -196,7 +198,8 @@ camel_offline_journal_replay (CamelOfflineJournal *journal,
 	entry = journal->queue.head;
 	while (entry->next) {
 		next = entry->next;
-		if (CAMEL_OFFLINE_JOURNAL_GET_CLASS (journal)->entry_play (journal, entry, &local_error) == -1) {
+		if (CAMEL_OFFLINE_JOURNAL_GET_CLASS (journal)->entry_play (
+			journal, entry, cancellable, &local_error) == -1) {
 			if (failed == 0) {
 				g_propagate_error (error, local_error);
 				local_error = NULL;
diff --git a/camel/camel-offline-journal.h b/camel/camel-offline-journal.h
index f280449..c8cdda0 100644
--- a/camel/camel-offline-journal.h
+++ b/camel/camel-offline-journal.h
@@ -71,21 +71,31 @@ struct _CamelOfflineJournal {
 struct _CamelOfflineJournalClass {
 	CamelObjectClass parent_class;
 
-	/* entry methods */
-	void (* entry_free) (CamelOfflineJournal *journal, CamelDListNode *entry);
-
-	CamelDListNode * (* entry_load) (CamelOfflineJournal *journal, FILE *in);
-	gint (* entry_write) (CamelOfflineJournal *journal, CamelDListNode *entry, FILE *out);
-	gint (* entry_play) (CamelOfflineJournal *journal, CamelDListNode *entry, GError **error);
+	void		(*entry_free)		(CamelOfflineJournal *journal,
+						 CamelDListNode *entry);
+	CamelDListNode *(*entry_load)		(CamelOfflineJournal *journal,
+						 FILE *in);
+	gint		(*entry_write)		(CamelOfflineJournal *journal,
+						 CamelDListNode *entry,
+						 FILE *out);
+	gint		(*entry_play)		(CamelOfflineJournal *journal,
+						 CamelDListNode *entry,
+						 GCancellable *cancellable,
+						 GError **error);
 };
 
-GType camel_offline_journal_get_type (void);
-
-void camel_offline_journal_construct (CamelOfflineJournal *journal, struct _CamelFolder *folder, const gchar *filename);
-void camel_offline_journal_set_filename (CamelOfflineJournal *journal, const gchar *filename);
-
-gint camel_offline_journal_write (CamelOfflineJournal *journal, GError **error);
-gint camel_offline_journal_replay (CamelOfflineJournal *journal, GError **error);
+GType		camel_offline_journal_get_type	(void);
+void		camel_offline_journal_construct	(CamelOfflineJournal *journal,
+						 CamelFolder *folder,
+						 const gchar *filename);
+void		camel_offline_journal_set_filename
+						(CamelOfflineJournal *journal,
+						 const gchar *filename);
+gint		camel_offline_journal_write	(CamelOfflineJournal *journal,
+						 GError **error);
+gint		camel_offline_journal_replay	(CamelOfflineJournal *journal,
+						 GCancellable *cancellable,
+						 GError **error);
 
 G_END_DECLS
 
diff --git a/camel/camel-offline-store.c b/camel/camel-offline-store.c
index aefd401..168657b 100644
--- a/camel/camel-offline-store.c
+++ b/camel/camel-offline-store.c
@@ -91,6 +91,7 @@ camel_offline_store_get_network_state (CamelOfflineStore *store,
  * camel_offline_store_set_network_state:
  * @store: a #CamelOfflineStore object
  * @state: the network state
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Set the network state to either #CAMEL_OFFLINE_STORE_NETWORK_AVAIL
@@ -99,6 +100,7 @@ camel_offline_store_get_network_state (CamelOfflineStore *store,
 gboolean
 camel_offline_store_set_network_state (CamelOfflineStore *store,
                                        gint state,
+                                       GCancellable *cancellable,
                                        GError **error)
 {
 	CamelService *service = CAMEL_SERVICE (store);
@@ -126,7 +128,9 @@ camel_offline_store_set_network_state (CamelOfflineStore *store,
 
 					if (G_TYPE_CHECK_INSTANCE_TYPE (folder, CAMEL_TYPE_OFFLINE_FOLDER)
 					    && (sync || camel_offline_folder_get_offline_sync (CAMEL_OFFLINE_FOLDER (folder)))) {
-						camel_offline_folder_downsync ((CamelOfflineFolder *) folder, NULL, NULL);
+						camel_offline_folder_downsync (
+							(CamelOfflineFolder *) folder,
+							NULL, cancellable, NULL);
 					}
 
 					g_object_unref (folder);
@@ -135,7 +139,9 @@ camel_offline_store_set_network_state (CamelOfflineStore *store,
 				g_ptr_array_free (folders, TRUE);
 			}
 
-			camel_store_sync (CAMEL_STORE (store), FALSE, NULL);
+			camel_store_sync (
+				CAMEL_STORE (store),
+				FALSE, cancellable, NULL);
 		}
 
 		if (!camel_service_disconnect (CAMEL_SERVICE (store), network_available, error))
@@ -161,6 +167,7 @@ camel_offline_store_set_network_state (CamelOfflineStore *store,
  **/
 gboolean
 camel_offline_store_prepare_for_offline (CamelOfflineStore *store,
+                                         GCancellable *cancellable,
                                          GError **error)
 {
 	CamelService *service = CAMEL_SERVICE (store);
@@ -183,7 +190,7 @@ camel_offline_store_prepare_for_offline (CamelOfflineStore *store,
 
 					if (G_TYPE_CHECK_INSTANCE_TYPE (folder, CAMEL_TYPE_OFFLINE_FOLDER)
 					    && (sync || camel_offline_folder_get_offline_sync (CAMEL_OFFLINE_FOLDER (folder)))) {
-						camel_offline_folder_downsync ((CamelOfflineFolder *) folder, NULL, NULL);
+						camel_offline_folder_downsync ((CamelOfflineFolder *) folder, NULL, cancellable, NULL);
 					}
 					g_object_unref (folder);
 				}
@@ -191,7 +198,9 @@ camel_offline_store_prepare_for_offline (CamelOfflineStore *store,
 			}
 		}
 
-		camel_store_sync (CAMEL_STORE (store), FALSE, NULL);
+		camel_store_sync (
+			CAMEL_STORE (store),
+			FALSE, cancellable, NULL);
 	}
 
 	return TRUE;
diff --git a/camel/camel-offline-store.h b/camel/camel-offline-store.h
index 8900f89..5d39870 100644
--- a/camel/camel-offline-store.h
+++ b/camel/camel-offline-store.h
@@ -67,15 +67,25 @@ struct _CamelOfflineStore {
 struct _CamelOfflineStoreClass {
 	CamelStoreClass parent_class;
 
-	gboolean (* set_network_state) (CamelOfflineStore *store, gint state, GError **error);
+	gboolean	(*set_network_state)	(CamelOfflineStore *store,
+						 gint state,
+						 GCancellable *cancellable,
+						 GError **error);
 };
 
-GType camel_offline_store_get_type (void);
-
-gboolean camel_offline_store_set_network_state (CamelOfflineStore *store, gint state, GError **error);
-gint camel_offline_store_get_network_state (CamelOfflineStore *store, GError **error);
-
-gboolean camel_offline_store_prepare_for_offline (CamelOfflineStore *store, GError **error);
+GType		camel_offline_store_get_type (void);
+gboolean	camel_offline_store_set_network_state
+						(CamelOfflineStore *store,
+						 gint state,
+						 GCancellable *cancellable,
+						 GError **error);
+gint		camel_offline_store_get_network_state
+						(CamelOfflineStore *store,
+						 GError **error);
+gboolean	camel_offline_store_prepare_for_offline
+						(CamelOfflineStore *store,
+						 GCancellable *cancellable,
+						 GError **error);
 
 G_END_DECLS
 
diff --git a/camel/camel-operation.c b/camel/camel-operation.c
index e03702f..82c6989 100644
--- a/camel/camel-operation.c
+++ b/camel/camel-operation.c
@@ -74,7 +74,6 @@ static GStaticRecMutex operation_lock = G_STATIC_REC_MUTEX_INIT;
 #define UNLOCK() g_static_rec_mutex_unlock (&operation_lock)
 
 static GQueue operation_list = G_QUEUE_INIT;
-static GStaticPrivate operation_key = G_STATIC_PRIVATE_INIT;
 
 static guint signals[LAST_SIGNAL];
 
@@ -98,12 +97,6 @@ status_node_free (StatusNode *node)
 	g_slice_free (StatusNode, node);
 }
 
-static CamelOperation *
-co_getcc (void)
-{
-	return (CamelOperation *) g_static_private_get (&operation_key);
-}
-
 static guint
 stamp (void)
 {
@@ -262,22 +255,6 @@ camel_operation_new (void)
 }
 
 /**
- * camel_operation_registered:
- *
- * Returns: the registered operation, or %NULL if none registered.
- **/
-CamelOperation *
-camel_operation_registered (void)
-{
-	CamelOperation *operation = co_getcc ();
-
-	if (operation != NULL)
-		g_object_ref (operation);
-
-	return operation;
-}
-
-/**
  * camel_operation_cancel:
  * @operation: a #CamelOperation
  *
@@ -325,8 +302,7 @@ camel_operation_cancel (CamelOperation *operation)
  * camel_operation_uncancel:
  * @operation: a #CamelOperation
  *
- * Uncancel a cancelled operation.  If @operation is %NULL then the current
- * operation is uncancelled.
+ * Uncancel a cancelled operation.
  *
  * This is useful, if e.g. you need to do some cleaning up where a
  * cancellation lying around in the same thread will abort any
@@ -335,9 +311,6 @@ camel_operation_cancel (CamelOperation *operation)
 void
 camel_operation_uncancel (CamelOperation *operation)
 {
-	if (operation == NULL)
-		operation = co_getcc ();
-
 	if (operation != NULL) {
 		g_return_if_fail (CAMEL_IS_OPERATION (operation));
 		operation_flush_msgport (operation);
@@ -346,45 +319,10 @@ camel_operation_uncancel (CamelOperation *operation)
 }
 
 /**
- * camel_operation_register:
- * @operation: a #CamelOperation
- *
- * Register a thread or the main thread for cancellation through @operation.
- * If @operation is NULL, then a new cancellation is created for this thread.
- *
- * All calls to camel_operation_register() should save their value and
- * call * camel_operation_register() again with that, to automatically
- * stack * registrations.
- *
- * Returns: the previously registered operatoin.
- **/
-CamelOperation *
-camel_operation_register (CamelOperation *operation)
-{
-	CamelOperation *old_operation = co_getcc ();
-
-	g_static_private_set (&operation_key, operation, NULL);
-
-	return old_operation;
-}
-
-/**
- * camel_operation_unregister:
- *
- * Unregister the current thread for all cancellations.
- **/
-void
-camel_operation_unregister (void)
-{
-	g_static_private_set (&operation_key, NULL, NULL);
-}
-
-/**
  * camel_operation_cancel_check:
  * @operation: a #CamelOperation
  *
- * Check if cancellation has been applied to @operation.  If @operation is
- * %NULL, then the #CamelOperation registered for the current thread is used.
+ * Check if cancellation has been applied to @operation.
  *
  * Returns: %TRUE if the operation has been cancelled
  **/
@@ -394,9 +332,6 @@ camel_operation_cancel_check (CamelOperation *operation)
 	gboolean cancelled;
 
 	if (operation == NULL)
-		operation = co_getcc ();
-
-	if (operation == NULL)
 		return FALSE;
 
 	LOCK ();
@@ -425,9 +360,6 @@ gint
 camel_operation_cancel_fd (CamelOperation *operation)
 {
 	if (operation == NULL)
-		operation = co_getcc ();
-
-	if (operation == NULL)
 		return -1;
 
 	return g_cancellable_get_fd (G_CANCELLABLE (operation));
@@ -450,9 +382,6 @@ camel_operation_cancel_prfd (CamelOperation *operation)
 	CamelOperationPrivate *priv;
 
 	if (operation == NULL)
-		operation = co_getcc ();
-
-	if (operation == NULL)
 		return NULL;
 
 	LOCK ();
@@ -470,32 +399,41 @@ camel_operation_cancel_prfd (CamelOperation *operation)
 
 /**
  * camel_operation_start:
- * @operation: a #CamelOperation
+ * @cancellable: a #GCancellable or %NULL
  * @what: action being performed (printf-style format string)
  * @Varargs: varargs
  *
  * Report the start of an operation.  All start operations should have
  * similar end operations.
+ *
+ * This function only works if @cancellable is a #CamelOperation cast as a
+ * #GCancellable.  If @cancellable is a plain #GCancellable or %NULL, the
+ * function does nothing and returns silently.
  **/
 void
-camel_operation_start (CamelOperation *operation,
+camel_operation_start (GCancellable *cancellable,
                        const gchar *what, ...)
 {
+	CamelOperation *operation;
 	const guint signal_id = signals[STATUS];
 	StatusNode *node;
 	va_list ap;
 
-	if (operation == NULL)
-		operation = co_getcc ();
+	if (cancellable == NULL)
+		return;
 
-	if (operation == NULL)
+	if (G_OBJECT_TYPE (cancellable) == G_TYPE_CANCELLABLE)
 		return;
 
-	if (!g_signal_has_handler_pending (operation, signal_id, 0, TRUE))
+	g_return_if_fail (CAMEL_IS_OPERATION (cancellable));
+
+	if (!g_signal_has_handler_pending (cancellable, signal_id, 0, TRUE))
 		return;
 
 	LOCK ();
 
+	operation = CAMEL_OPERATION (cancellable);
+
 	operation->priv->status_update = 0;
 
 	va_start (ap, what);
@@ -512,29 +450,38 @@ camel_operation_start (CamelOperation *operation,
 
 /**
  * camel_operation_start_transient:
- * @operation: a #CamelOperation
+ * @cancellable: a #GCancellable or %NULL
  * @what: printf-style format string describing the action being performed
  * @Varargs: varargs
  *
  * Start a transient event.  We only update this to the display if it
  * takes very long to process, and if we do, we then go back to the
  * previous state when finished.
+ *
+ * This function only works if @cancellable is a #CamelOperation cast as a
+ * #GCancellable.  If @cancellable is a plain #GCancellable or %NULL, the
+ * function does nothing and returns silently.
  **/
 void
-camel_operation_start_transient (CamelOperation *operation,
+camel_operation_start_transient (GCancellable *cancellable,
                                  const gchar *what, ...)
 {
+	CamelOperation *operation;
 	StatusNode *node;
 	va_list ap;
 
-	if (operation == NULL)
-		operation = co_getcc ();
+	if (cancellable == NULL)
+		return;
 
-	if (operation == NULL)
+	if (G_OBJECT_TYPE (cancellable) == G_TYPE_CANCELLABLE)
 		return;
 
+	g_return_if_fail (CAMEL_IS_OPERATION (cancellable));
+
 	LOCK ();
 
+	operation = CAMEL_OPERATION (cancellable);
+
 	operation->priv->status_update = 0;
 
 	va_start (ap, what);
@@ -551,36 +498,40 @@ camel_operation_start_transient (CamelOperation *operation,
 
 /**
  * camel_operation_progress:
- * @operation: a #CamelOperation
- * @pc: Percent complete, 0 to 100.
+ * @cancellable: a #GCancellable or %NULL
+ * @pc: percent complete, 0 to 100.
  *
- * Report progress on the current operation.  If @operation is %NULL, then
- * the currently registered operation is used.  @pc reports the current
+ * Report progress on the current operation.  @pc reports the current
  * percentage of completion, which should be in the range of 0 to 100.
  *
- * If the total percentage is not know, then use
- * camel_operation_progress_count().
+ * This function only works if @cancellable is a #CamelOperation cast as a
+ * #GCancellable.  If @cancellable is a plain #GCancellable or %NULL, the
+ * function does nothing and returns silently.
  **/
 void
-camel_operation_progress (CamelOperation *operation,
+camel_operation_progress (GCancellable *cancellable,
                           gint pc)
 {
+	CamelOperation *operation;
 	const guint signal_id = signals[STATUS];
 	CamelOperationPrivate *priv;
 	guint now;
 	StatusNode *node;
 
-	if (operation == NULL)
-		operation = co_getcc ();
+	if (cancellable == NULL)
+		return;
 
-	if (operation == NULL)
+	if (G_OBJECT_TYPE (cancellable) == G_TYPE_CANCELLABLE)
 		return;
 
-	if (!g_signal_has_handler_pending (operation, signal_id, 0, TRUE))
+	g_return_if_fail (CAMEL_IS_OPERATION (cancellable));
+
+	if (!g_signal_has_handler_pending (cancellable, signal_id, 0, TRUE))
 		return;
 
 	LOCK ();
 
+	operation = CAMEL_OPERATION (cancellable);
 	priv = operation->priv;
 
 	if (g_queue_is_empty (&priv->status_stack)) {
@@ -614,29 +565,37 @@ camel_operation_progress (CamelOperation *operation,
 
 /**
  * camel_operation_end:
- * @operation: a #CamelOperation
+ * @cancellable: a #GCancellable
  *
- * Report the end of an operation.  If @operation is %NULL, then the
- * currently registered operation is notified.
+ * Report the end of an operation.
+ *
+ * This function only works if @cancellable is a #CamelOperation cast as a
+ * #GCancellable.  If @cancellable is a plain #GCancellable or %NULL, the
+ * function does nothing and returns silently.
  **/
 void
-camel_operation_end (CamelOperation *operation)
+camel_operation_end (GCancellable *cancellable)
 {
+	CamelOperation *operation;
 	const guint signal_id = signals[STATUS];
 	GQueue *status_stack;
 	StatusNode *node;
 
-	if (operation == NULL)
-		operation = co_getcc ();
+	if (cancellable == NULL)
+		return;
 
-	if (operation == NULL)
+	if (G_OBJECT_TYPE (cancellable) == G_TYPE_CANCELLABLE)
 		return;
 
-	if (!g_signal_has_handler_pending (operation, signal_id, 0, TRUE))
+	g_return_if_fail (CAMEL_IS_OPERATION (cancellable));
+
+	if (!g_signal_has_handler_pending (cancellable, signal_id, 0, TRUE))
 		return;
 
 	LOCK ();
 
+	operation = CAMEL_OPERATION (cancellable);
+
 	status_stack = &operation->priv->status_stack;
 
 	if ((node = g_queue_pop_head (status_stack)) != NULL) {
diff --git a/camel/camel-operation.h b/camel/camel-operation.h
index ec35a4f..6b6b549 100644
--- a/camel/camel-operation.h
+++ b/camel/camel-operation.h
@@ -71,10 +71,6 @@ CamelOperation *camel_operation_new		(void);
 void		camel_operation_cancel		(CamelOperation *operation);
 void		camel_operation_uncancel	(CamelOperation *operation);
 
-/* subthread functions */
-CamelOperation *camel_operation_register	(CamelOperation *operation);
-void		camel_operation_unregister	(void);
-
 /* called internally by camel, for the current thread */
 gboolean	camel_operation_cancel_check	(CamelOperation *operation);
 gint		camel_operation_cancel_fd	(CamelOperation *operation);
@@ -83,18 +79,20 @@ struct PRFileDesc *
 		camel_operation_cancel_prfd	(CamelOperation *operation);
 #endif
 
-/* return the registered operation for this thread, if there is one */
-CamelOperation *camel_operation_registered	(void);
+/* Since Camel methods pass around GCancellable pointers instead of
+ * CamelOperation pointers, it's more convenient to callers to take
+ * a GCancellable pointer and just return silently if the pointer is
+ * NULL or the pointed to object actually is a plain GCancellable. */
 
-void		camel_operation_start		(CamelOperation *cc,
+void		camel_operation_start		(GCancellable *cancellable,
 						 const gchar *what,
 						 ...) G_GNUC_PRINTF (2, 3);
-void		camel_operation_start_transient	(CamelOperation *cc,
+void		camel_operation_start_transient	(GCancellable *cancellable,
 						 const gchar *what,
 						 ...) G_GNUC_PRINTF (2, 3);
-void		camel_operation_progress	(CamelOperation *operation,
+void		camel_operation_progress	(GCancellable *cancellable,
 						 gint pc);
-void		camel_operation_end		(CamelOperation *operation);
+void		camel_operation_end		(GCancellable *cancellable);
 
 G_END_DECLS
 
diff --git a/camel/camel-sasl-anonymous.c b/camel/camel-sasl-anonymous.c
index dbbb500..06bd930 100644
--- a/camel/camel-sasl-anonymous.c
+++ b/camel/camel-sasl-anonymous.c
@@ -56,6 +56,7 @@ sasl_anonymous_finalize (GObject *object)
 static GByteArray *
 sasl_anonymous_challenge (CamelSasl *sasl,
                           GByteArray *token,
+                          GCancellable *cancellable,
                           GError **error)
 {
 	CamelSaslAnonymous *sasl_anon = CAMEL_SASL_ANONYMOUS (sasl);
diff --git a/camel/camel-sasl-cram-md5.c b/camel/camel-sasl-cram-md5.c
index ae4bb16..ed087e9 100644
--- a/camel/camel-sasl-cram-md5.c
+++ b/camel/camel-sasl-cram-md5.c
@@ -60,6 +60,7 @@ G_DEFINE_TYPE (CamelSaslCramMd5, camel_sasl_cram_md5, CAMEL_TYPE_SASL)
 static GByteArray *
 sasl_cram_md5_challenge (CamelSasl *sasl,
                          GByteArray *token,
+                         GCancellable *cancellable,
                          GError **error)
 {
 	CamelService *service;
diff --git a/camel/camel-sasl-digest-md5.c b/camel/camel-sasl-digest-md5.c
index 36ea3db..a90a52f 100644
--- a/camel/camel-sasl-digest-md5.c
+++ b/camel/camel-sasl-digest-md5.c
@@ -789,6 +789,7 @@ sasl_digest_md5_finalize (GObject *object)
 static GByteArray *
 sasl_digest_md5_challenge (CamelSasl *sasl,
                            GByteArray *token,
+                           GCancellable *cancellable,
                            GError **error)
 {
 	CamelSaslDigestMd5 *sasl_digest = CAMEL_SASL_DIGEST_MD5 (sasl);
@@ -843,7 +844,10 @@ sasl_digest_md5_challenge (CamelSasl *sasl,
 
 		memset (&hints, 0, sizeof (hints));
 		hints.ai_flags = AI_CANONNAME;
-		ai = camel_getaddrinfo(service->url->host?service->url->host:"localhost", NULL, &hints, NULL);
+		ai = camel_getaddrinfo (
+			service->url->host ?
+			service->url->host : "localhost",
+			NULL, &hints, cancellable, NULL);
 		if (ai && ai->ai_canonname)
 			ptr = ai->ai_canonname;
 		else
diff --git a/camel/camel-sasl-gssapi.c b/camel/camel-sasl-gssapi.c
index f736be9..8edaf00 100644
--- a/camel/camel-sasl-gssapi.c
+++ b/camel/camel-sasl-gssapi.c
@@ -243,6 +243,7 @@ send_dbus_message (gchar *name)
 static GByteArray *
 sasl_gssapi_challenge (CamelSasl *sasl,
                        GByteArray *token,
+                       GCancellable *cancellable,
                        GError **error)
 {
 	CamelSaslGssapiPrivate *priv;
@@ -267,7 +268,10 @@ sasl_gssapi_challenge (CamelSasl *sasl,
 	case GSSAPI_STATE_INIT:
 		memset (&hints, 0, sizeof (hints));
 		hints.ai_flags = AI_CANONNAME;
-		ai = camel_getaddrinfo(service->url->host?service->url->host:"localhost", NULL, &hints, error);
+		ai = camel_getaddrinfo (
+			service->url->host ?
+			service->url->host : "localhost",
+			NULL, &hints, cancellable, error);
 		if (ai == NULL)
 			return NULL;
 
diff --git a/camel/camel-sasl-login.c b/camel/camel-sasl-login.c
index de3aba4..66554f8 100644
--- a/camel/camel-sasl-login.c
+++ b/camel/camel-sasl-login.c
@@ -59,6 +59,7 @@ G_DEFINE_TYPE (CamelSaslLogin, camel_sasl_login, CAMEL_TYPE_SASL)
 static GByteArray *
 sasl_login_challenge (CamelSasl *sasl,
                       GByteArray *token,
+                      GCancellable *cancellable,
                       GError **error)
 {
 	CamelSaslLoginPrivate *priv;
diff --git a/camel/camel-sasl-ntlm.c b/camel/camel-sasl-ntlm.c
index bfa2b1d..b59f551 100644
--- a/camel/camel-sasl-ntlm.c
+++ b/camel/camel-sasl-ntlm.c
@@ -661,6 +661,7 @@ deskey (DES_KS k, guchar *key, gint decrypt)
 static GByteArray *
 sasl_ntlm_challenge (CamelSasl *sasl,
                      GByteArray *token,
+                     GCancellable *cancellable,
                      GError **error)
 {
 	CamelService *service;
diff --git a/camel/camel-sasl-plain.c b/camel/camel-sasl-plain.c
index e27a6b9..3d67209 100644
--- a/camel/camel-sasl-plain.c
+++ b/camel/camel-sasl-plain.c
@@ -54,6 +54,7 @@ G_DEFINE_TYPE (CamelSaslPlain, camel_sasl_plain, CAMEL_TYPE_SASL)
 static GByteArray *
 sasl_plain_challenge (CamelSasl *sasl,
                       GByteArray *token,
+                      GCancellable *cancellable,
                       GError **error)
 {
 	GByteArray *buf = NULL;
diff --git a/camel/camel-sasl-popb4smtp.c b/camel/camel-sasl-popb4smtp.c
index 870a109..d91f366 100644
--- a/camel/camel-sasl-popb4smtp.c
+++ b/camel/camel-sasl-popb4smtp.c
@@ -66,6 +66,7 @@ G_DEFINE_TYPE (CamelSaslPOPB4SMTP, camel_sasl_popb4smtp, CAMEL_TYPE_SASL)
 static GByteArray *
 sasl_popb4smtp_challenge (CamelSasl *sasl,
                           GByteArray *token,
+                          GCancellable *cancellable,
                           GError **error)
 {
 	gchar *popuri;
diff --git a/camel/camel-sasl.c b/camel/camel-sasl.c
index 8a616ce..fe89e99 100644
--- a/camel/camel-sasl.c
+++ b/camel/camel-sasl.c
@@ -258,6 +258,7 @@ camel_sasl_init (CamelSasl *sasl)
  * camel_sasl_challenge:
  * @sasl: a #CamelSasl object
  * @token: a token, or %NULL
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * If @token is %NULL, generate the initial SASL message to send to
@@ -265,12 +266,13 @@ camel_sasl_init (CamelSasl *sasl)
  * exchange.) Otherwise, @token is a challenge from the server, and
  * the return value is the response.
  *
- * Returns: the SASL response or %NULL. If an error occurred, @ex will
+ * Returns: the SASL response or %NULL. If an error occurred, @error will
  * also be set.
  **/
 GByteArray *
 camel_sasl_challenge (CamelSasl *sasl,
                       GByteArray *token,
+                      GCancellable *cancellable,
                       GError **error)
 {
 	CamelSaslClass *class;
@@ -281,7 +283,7 @@ camel_sasl_challenge (CamelSasl *sasl,
 	class = CAMEL_SASL_GET_CLASS (sasl);
 	g_return_val_if_fail (class->challenge != NULL, NULL);
 
-	response = class->challenge (sasl, token, error);
+	response = class->challenge (sasl, token, cancellable, error);
 	if (token)
 		CAMEL_CHECK_GERROR (sasl, challenge, response != NULL, error);
 
@@ -292,6 +294,7 @@ camel_sasl_challenge (CamelSasl *sasl,
  * camel_sasl_challenge_base64:
  * @sasl: a #CamelSasl object
  * @token: a base64-encoded token
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * As with #camel_sasl_challenge, but the challenge @token and the
@@ -302,6 +305,7 @@ camel_sasl_challenge (CamelSasl *sasl,
 gchar *
 camel_sasl_challenge_base64 (CamelSasl *sasl,
                              const gchar *token,
+                             GCancellable *cancellable,
                              GError **error)
 {
 	GByteArray *token_binary, *ret_binary;
@@ -320,7 +324,8 @@ camel_sasl_challenge_base64 (CamelSasl *sasl,
 	} else
 		token_binary = NULL;
 
-	ret_binary = camel_sasl_challenge (sasl, token_binary, error);
+	ret_binary = camel_sasl_challenge (
+		sasl, token_binary, cancellable, error);
 	if (token_binary)
 		g_byte_array_free (token_binary, TRUE);
 	if (!ret_binary)
diff --git a/camel/camel-sasl.h b/camel/camel-sasl.h
index 3bf3dc8..01ff9d6 100644
--- a/camel/camel-sasl.h
+++ b/camel/camel-sasl.h
@@ -65,15 +65,18 @@ struct _CamelSaslClass {
 
 	GByteArray *	(*challenge)		(CamelSasl *sasl,
 						 GByteArray *token,
+						 GCancellable *cancellable,
 						 GError **error);
 };
 
 GType		camel_sasl_get_type		(void);
 GByteArray *	camel_sasl_challenge		(CamelSasl *sasl,
 						 GByteArray *token,
+						 GCancellable *cancellable,
 						 GError **error);
 gchar *		camel_sasl_challenge_base64	(CamelSasl *sasl,
 						 const gchar *token,
+						 GCancellable *cancellable,
 						 GError **error);
 CamelSasl *	camel_sasl_new			(const gchar *service_name,
 						 const gchar *mechanism,
diff --git a/camel/camel-search-private.c b/camel/camel-search-private.c
index d4a6c31..3058d35 100644
--- a/camel/camel-search-private.c
+++ b/camel/camel-search-private.c
@@ -479,8 +479,8 @@ camel_search_message_body_contains (CamelDataWrapper *object, regex_t *pattern)
 
 		byte_array = g_byte_array_new ();
 		stream = camel_stream_mem_new_with_byte_array (byte_array);
-		camel_data_wrapper_write_to_stream (containee, stream, NULL);
-		camel_stream_write (stream, "", 1, NULL);
+		camel_data_wrapper_write_to_stream (containee, stream, NULL, NULL);
+		camel_stream_write (stream, "", 1, NULL, NULL);
 		truth = regexec (pattern, (gchar *) byte_array->data, 0, NULL, 0) == 0;
 		g_object_unref (stream);
 	}
diff --git a/camel/camel-seekable-substream.c b/camel/camel-seekable-substream.c
index 93685ef..f75dee0 100644
--- a/camel/camel-seekable-substream.c
+++ b/camel/camel-seekable-substream.c
@@ -63,6 +63,7 @@ static gssize
 seekable_substream_read (CamelStream *stream,
                          gchar *buffer,
                          gsize n,
+                         GCancellable *cancellable,
                          GError **error)
 {
 	CamelSeekableStream *parent;
@@ -90,7 +91,8 @@ seekable_substream_read (CamelStream *stream,
 		return 0;
 	}
 
-	v = camel_stream_read (CAMEL_STREAM (parent), buffer, n, error);
+	v = camel_stream_read (
+		CAMEL_STREAM (parent), buffer, n, cancellable, error);
 
 	/* ignore <0 - it's an error, let the caller deal */
 	if (v > 0)
@@ -103,6 +105,7 @@ static gssize
 seekable_substream_write (CamelStream *stream,
                           const gchar *buffer,
                           gsize n,
+                          GCancellable *cancellable,
                           GError **error)
 {
 	CamelSeekableStream *parent;
@@ -130,7 +133,8 @@ seekable_substream_write (CamelStream *stream,
 		return 0;
 	}
 
-	v = camel_stream_write (CAMEL_STREAM (parent), buffer, n, error);
+	v = camel_stream_write (
+		CAMEL_STREAM (parent), buffer, n, cancellable, error);
 
 	/* ignore <0 - it's an error, let the caller deal */
 	if (v > 0)
@@ -142,15 +146,18 @@ seekable_substream_write (CamelStream *stream,
 
 static gint
 seekable_substream_flush (CamelStream *stream,
+                          GCancellable *cancellable,
                           GError **error)
 {
 	CamelSeekableSubstream *sus = (CamelSeekableSubstream *)stream;
 
-	return camel_stream_flush (CAMEL_STREAM (sus->parent_stream), error);
+	return camel_stream_flush (
+		CAMEL_STREAM (sus->parent_stream), cancellable, error);
 }
 
 static gint
 seekable_substream_close (CamelStream *stream,
+                          GCancellable *cancellable,
                           GError **error)
 {
 	/* we dont really want to close the substream ... */
diff --git a/camel/camel-service.c b/camel/camel-service.c
index b767db5..c385b04 100644
--- a/camel/camel-service.c
+++ b/camel/camel-service.c
@@ -59,7 +59,8 @@ service_finalize (GObject *object)
 	CamelService *service = CAMEL_SERVICE (object);
 
 	if (service->status == CAMEL_SERVICE_CONNECTED)
-		CAMEL_SERVICE_GET_CLASS (service)->disconnect (service, TRUE, NULL);
+		CAMEL_SERVICE_GET_CLASS (service)->disconnect (
+			service, TRUE, NULL, NULL);
 
 	if (service->url)
 		camel_url_free (service->url);
@@ -118,6 +119,7 @@ fail:
 
 static gboolean
 service_connect (CamelService *service,
+                 GCancellable *cancellable,
                  GError **error)
 {
 	/* Things like the CamelMboxStore can validly
@@ -128,6 +130,7 @@ service_connect (CamelService *service,
 static gboolean
 service_disconnect (CamelService *service,
                     gboolean clean,
+                    GCancellable *cancellable,
                     GError **error)
 {
 	/* We let people get away with not having a disconnect
@@ -138,11 +141,12 @@ service_disconnect (CamelService *service,
 static void
 service_cancel_connect (CamelService *service)
 {
-	camel_operation_cancel (service->connect_op);
+	g_cancellable_cancel (service->connect_op);
 }
 
 static GList *
 service_query_auth_types (CamelService *service,
+                          GCancellable *cancellable,
                           GError **error)
 {
 	return NULL;
@@ -293,8 +297,6 @@ camel_service_connect (CamelService *service,
 {
 	CamelServiceClass *class;
 	gboolean ret = FALSE;
-	gboolean unreg = FALSE;
-	CamelOperation *connect_op;
 
 	g_return_val_if_fail (CAMEL_IS_SERVICE (service), FALSE);
 	g_return_val_if_fail (service->session != NULL, FALSE);
@@ -313,28 +315,17 @@ camel_service_connect (CamelService *service,
 	/* Register a separate operation for connecting, so that
 	 * the offline code can cancel it. */
 	camel_service_lock (service, CAMEL_SERVICE_CONNECT_OP_LOCK);
-	service->connect_op = camel_operation_registered ();
-	if (!service->connect_op) {
-		service->connect_op = camel_operation_new ();
-		camel_operation_register (service->connect_op);
-		unreg = TRUE;
-	}
-	connect_op = service->connect_op;
+	service->connect_op = (GCancellable *) camel_operation_new ();
 	camel_service_unlock (service, CAMEL_SERVICE_CONNECT_OP_LOCK);
 
 	service->status = CAMEL_SERVICE_CONNECTING;
-	ret = class->connect (service, error);
+	ret = class->connect (service, service->connect_op, error);
 	CAMEL_CHECK_GERROR (service, connect, ret, error);
 	service->status = ret ? CAMEL_SERVICE_CONNECTED : CAMEL_SERVICE_DISCONNECTED;
 
 	camel_service_lock (service, CAMEL_SERVICE_CONNECT_OP_LOCK);
-	if (connect_op) {
-		if (unreg && service->connect_op)
-			camel_operation_unregister ();
-
-		g_object_unref (connect_op);
-		service->connect_op = NULL;
-	}
+	g_object_unref (service->connect_op);
+	service->connect_op = NULL;
 	camel_service_unlock (service, CAMEL_SERVICE_CONNECT_OP_LOCK);
 
 	camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
@@ -360,7 +351,6 @@ camel_service_disconnect (CamelService *service,
 {
 	CamelServiceClass *class;
 	gboolean res = TRUE;
-	gint unreg = FALSE;
 
 	g_return_val_if_fail (CAMEL_IS_SERVICE (service), FALSE);
 
@@ -372,23 +362,16 @@ camel_service_disconnect (CamelService *service,
 	if (service->status != CAMEL_SERVICE_DISCONNECTED
 	    && service->status != CAMEL_SERVICE_DISCONNECTING) {
 		camel_service_lock (service, CAMEL_SERVICE_CONNECT_OP_LOCK);
-		service->connect_op = camel_operation_registered ();
-		if (!service->connect_op) {
-			service->connect_op = camel_operation_new ();
-			camel_operation_register (service->connect_op);
-			unreg = TRUE;
-		}
+		service->connect_op = (GCancellable *) camel_operation_new ();
 		camel_service_unlock (service, CAMEL_SERVICE_CONNECT_OP_LOCK);
 
 		service->status = CAMEL_SERVICE_DISCONNECTING;
-		res = class->disconnect (service, clean, error);
+		res = class->disconnect (
+			service, clean, service->connect_op, error);
 		CAMEL_CHECK_GERROR (service, disconnect, res, error);
 		service->status = CAMEL_SERVICE_DISCONNECTED;
 
 		camel_service_lock (service, CAMEL_SERVICE_CONNECT_OP_LOCK);
-		if (unreg)
-			camel_operation_unregister ();
-
 		g_object_unref (service->connect_op);
 		service->connect_op = NULL;
 		camel_service_unlock (service, CAMEL_SERVICE_CONNECT_OP_LOCK);
@@ -531,6 +514,7 @@ camel_service_get_provider (CamelService *service)
 /**
  * camel_service_query_auth_types:
  * @service: a #CamelService object
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * This is used by the mail source wizard to get the list of
@@ -542,6 +526,7 @@ camel_service_get_provider (CamelService *service)
  **/
 GList *
 camel_service_query_auth_types (CamelService *service,
+                                GCancellable *cancellable,
                                 GError **error)
 {
 	CamelServiceClass *class;
@@ -555,7 +540,7 @@ camel_service_query_auth_types (CamelService *service,
 	/* Note that we get the connect lock here, which means the
 	 * callee must not call the connect functions itself. */
 	camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
-	ret = class->query_auth_types (service, error);
+	ret = class->query_auth_types (service, cancellable, error);
 	camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
 
 	return ret;
diff --git a/camel/camel-service.h b/camel/camel-service.h
index d1efa89..c500bed 100644
--- a/camel/camel-service.h
+++ b/camel/camel-service.h
@@ -106,7 +106,7 @@ struct _CamelService {
 	struct _CamelSession *session;
 	CamelProvider *provider;
 	CamelServiceConnectionStatus status;
-	CamelOperation *connect_op;
+	GCancellable *connect_op;
 	CamelURL *url;
 };
 
@@ -119,12 +119,15 @@ struct _CamelServiceClass {
 						 CamelURL *url,
 						 GError **error);
 	gboolean	(*connect)		(CamelService *service,
+						 GCancellable *cancellable,
 						 GError **error);
 	gboolean	(*disconnect)		(CamelService *service,
 						 gboolean clean,
+						 GCancellable *cancellable,
 						 GError **error);
 	void		(*cancel_connect)	(CamelService *service);
 	GList *		(*query_auth_types)	(CamelService *service,
+						 GCancellable *cancellable,
 						 GError **error);
 	gchar *		(*get_name)		(CamelService *service,
 						 gboolean brief);
@@ -161,6 +164,7 @@ struct _CamelSession *
 		camel_service_get_session	(CamelService *service);
 CamelProvider *	camel_service_get_provider	(CamelService *service);
 GList *		camel_service_query_auth_types	(CamelService *service,
+						 GCancellable *cancellable,
 						 GError **error);
 void		camel_service_lock		(CamelService *service,
 						 CamelServiceLock lock);
diff --git a/camel/camel-session.c b/camel/camel-session.c
index 8a08fbe..abf297d 100644
--- a/camel/camel-session.c
+++ b/camel/camel-session.c
@@ -83,7 +83,7 @@ enum {
 G_DEFINE_TYPE (CamelSession, camel_session, CAMEL_TYPE_OBJECT)
 
 static void
-cs_thread_status (CamelOperation *op,
+cs_thread_status (CamelOperation *operation,
                   const gchar *what,
                   gint pc,
                   CamelSessionThreadMsg *msg)
@@ -276,15 +276,16 @@ session_thread_msg_new (CamelSession *session,
 	m = g_malloc0 (size);
 	m->ops = ops;
 	m->session = g_object_ref (session);
-	m->op = camel_operation_new ();
-	g_signal_connect (
-		m->op, "status",
-		G_CALLBACK (cs_thread_status), m);
+	m->cancellable = (GCancellable *) camel_operation_new ();
 	camel_session_lock (session, CAMEL_SESSION_THREAD_LOCK);
 	m->id = session->priv->thread_id++;
 	g_hash_table_insert (session->priv->thread_active, GINT_TO_POINTER (m->id), m);
 	camel_session_unlock (session, CAMEL_SESSION_THREAD_LOCK);
 
+	g_signal_connect (
+		m->cancellable, "status",
+		G_CALLBACK (cs_thread_status), m);
+
 	return m;
 }
 
@@ -305,8 +306,8 @@ session_thread_msg_free (CamelSession *session,
 
 	if (msg->ops->free)
 		msg->ops->free (session, msg);
-	if (msg->op)
-		g_object_unref (msg->op);
+	if (msg->cancellable)
+		g_object_unref (msg->cancellable);
 	g_clear_error (&msg->error);
 	g_object_unref (msg->session);
 	g_free (msg);
@@ -316,13 +317,8 @@ static void
 session_thread_proxy (CamelSessionThreadMsg *msg,
                       CamelSession *session)
 {
-	if (msg->ops->receive) {
-		CamelOperation *oldop;
-
-		oldop = camel_operation_register (msg->op);
+	if (msg->ops->receive)
 		msg->ops->receive (session, msg);
-		camel_operation_register (oldop);
-	}
 
 	camel_session_thread_msg_free (session, msg);
 }
diff --git a/camel/camel-session.h b/camel/camel-session.h
index 5b4c032..59893fa 100644
--- a/camel/camel-session.h
+++ b/camel/camel-session.h
@@ -226,7 +226,7 @@ struct _CamelSessionThreadMsg {
 
 	GError *error;
 	CamelSessionThreadOps *ops;
-	CamelOperation *op;
+	GCancellable *cancellable;
 	CamelSession *session;
 
 	gpointer data;	/* Free for implementation to define, not
diff --git a/camel/camel-smime-context.c b/camel/camel-smime-context.c
index fdb35ff..98b0466 100644
--- a/camel/camel-smime-context.c
+++ b/camel/camel-smime-context.c
@@ -97,7 +97,7 @@ smime_cert_data_clone (gpointer cert_data)
 static void
 sm_write_stream (gpointer arg, const gchar *buf, gulong len)
 {
-	camel_stream_write ((CamelStream *)arg, buf, len, NULL);
+	camel_stream_write ((CamelStream *)arg, buf, len, NULL, NULL);
 }
 
 static PK11SymKey *
@@ -529,6 +529,7 @@ static CamelCipherValidity *
 sm_verify_cmsg (CamelCipherContext *context,
                 NSSCMSMessage *cmsg,
                 CamelStream *extstream,
+                GCancellable *cancellable,
                 GError **error)
 {
 	CamelSMIMEContextPrivate *p = ((CamelSMIMEContext *)context)->priv;
@@ -587,7 +588,7 @@ sm_verify_cmsg (CamelCipherContext *context,
 
 			buffer = g_byte_array_new ();
 			mem = camel_stream_mem_new_with_byte_array (buffer);
-			camel_stream_write_to_stream (extstream, mem, NULL);
+			camel_stream_write_to_stream (extstream, mem, cancellable, NULL);
 			NSS_CMSDigestContext_Update (digcx, buffer->data, buffer->len);
 			g_object_unref (mem);
 
@@ -764,6 +765,7 @@ smime_context_sign (CamelCipherContext *context,
                     CamelCipherHash hash,
                     CamelMimePart *ipart,
                     CamelMimePart *opart,
+                    GCancellable *cancellable,
                     GError **error)
 {
 	CamelCipherContextClass *class;
@@ -816,7 +818,7 @@ smime_context_sign (CamelCipherContext *context,
 		ipart, CAMEL_MIME_FILTER_CANON_STRIP |
 		CAMEL_MIME_FILTER_CANON_CRLF |
 		CAMEL_MIME_FILTER_CANON_FROM,
-		istream, error) == -1) {
+		istream, cancellable, error) == -1) {
 		g_prefix_error (
 			error, _("Could not generate signing data: "));
 		goto fail;
@@ -848,7 +850,7 @@ smime_context_sign (CamelCipherContext *context,
 
 	dw = camel_data_wrapper_new ();
 	camel_stream_reset (ostream, NULL);
-	camel_data_wrapper_construct_from_stream (dw, ostream, NULL);
+	camel_data_wrapper_construct_from_stream (dw, ostream, cancellable, NULL);
 	dw->encoding = CAMEL_TRANSFER_ENCODING_BINARY;
 
 	if (((CamelSMIMEContext *)context)->priv->sign_mode == CAMEL_SMIME_SIGN_CLEARSIGN) {
@@ -907,6 +909,7 @@ fail:
 static CamelCipherValidity *
 smime_context_verify (CamelCipherContext *context,
                       CamelMimePart *ipart,
+                      GCancellable *cancellable,
                       GError **error)
 {
 	CamelCipherContextClass *class;
@@ -974,7 +977,8 @@ smime_context_verify (CamelCipherContext *context,
 				   NULL, NULL); /* decrypt key callback */
 
 	camel_data_wrapper_decode_to_stream (
-		camel_medium_get_content (CAMEL_MEDIUM (sigpart)), mem, NULL);
+		camel_medium_get_content (
+			CAMEL_MEDIUM (sigpart)), mem, cancellable, NULL);
 	(void)NSS_CMSDecoder_Update (dec, (gchar *) buffer->data, buffer->len);
 	cmsg = NSS_CMSDecoder_Finish (dec);
 	if (cmsg == NULL) {
@@ -982,7 +986,7 @@ smime_context_verify (CamelCipherContext *context,
 		goto fail;
 	}
 
-	valid = sm_verify_cmsg (context, cmsg, constream, error);
+	valid = sm_verify_cmsg (context, cmsg, constream, cancellable, error);
 
 	NSS_CMSMessage_Destroy (cmsg);
 fail:
@@ -999,6 +1003,7 @@ smime_context_encrypt (CamelCipherContext *context,
                        GPtrArray *recipients,
                        CamelMimePart *ipart,
                        CamelMimePart *opart,
+                       GCancellable *cancellable,
                        GError **error)
 {
 	CamelSMIMEContextPrivate *p = ((CamelSMIMEContext *)context)->priv;
@@ -1118,7 +1123,7 @@ smime_context_encrypt (CamelCipherContext *context,
 	/* FIXME: Stream the input */
 	buffer = g_byte_array_new ();
 	mem = camel_stream_mem_new_with_byte_array (buffer);
-	camel_cipher_canonical_to_stream (ipart, CAMEL_MIME_FILTER_CANON_CRLF, mem, NULL);
+	camel_cipher_canonical_to_stream (ipart, CAMEL_MIME_FILTER_CANON_CRLF, mem, NULL, NULL);
 	if (NSS_CMSEncoder_Update (enc, (gchar *) buffer->data, buffer->len) != SECSuccess) {
 		NSS_CMSEncoder_Cancel (enc);
 		g_object_unref (mem);
@@ -1139,7 +1144,7 @@ smime_context_encrypt (CamelCipherContext *context,
 	PORT_FreeArena (poolp, PR_FALSE);
 
 	dw = camel_data_wrapper_new ();
-	camel_data_wrapper_construct_from_stream (dw, ostream, NULL);
+	camel_data_wrapper_construct_from_stream (dw, ostream, NULL, NULL);
 	g_object_unref (ostream);
 	dw->encoding = CAMEL_TRANSFER_ENCODING_BINARY;
 
@@ -1181,6 +1186,7 @@ static CamelCipherValidity *
 smime_context_decrypt (CamelCipherContext *context,
                        CamelMimePart *ipart,
                        CamelMimePart *opart,
+                       GCancellable *cancellable,
                        GError **error)
 {
 	NSSCMSDecoderContext *dec;
@@ -1200,7 +1206,8 @@ smime_context_decrypt (CamelCipherContext *context,
 	buffer = g_byte_array_new ();
 	istream = camel_stream_mem_new_with_byte_array (buffer);
 	camel_data_wrapper_decode_to_stream (
-		camel_medium_get_content ((CamelMedium *)ipart), istream, NULL);
+		camel_medium_get_content (CAMEL_MEDIUM (ipart)),
+		istream, NULL, NULL);
 	camel_stream_reset (istream, NULL);
 
 	dec = NSS_CMSDecoder_Start (NULL,
@@ -1231,11 +1238,12 @@ smime_context_decrypt (CamelCipherContext *context,
 #endif
 
 	camel_stream_reset (ostream, NULL);
-	camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)opart, ostream, NULL);
+	camel_data_wrapper_construct_from_stream (
+		CAMEL_DATA_WRAPPER (opart), ostream, NULL, NULL);
 
 	if (NSS_CMSMessage_IsSigned (cmsg)) {
 		camel_stream_reset (ostream, NULL);
-		valid = sm_verify_cmsg (context, cmsg, ostream, error);
+		valid = sm_verify_cmsg (context, cmsg, ostream, cancellable, error);
 	} else {
 		valid = camel_cipher_validity_new ();
 		valid->encrypt.description = g_strdup (_("Encrypted content"));
@@ -1344,7 +1352,7 @@ camel_smime_context_describe_part (CamelSMIMEContext *context, CamelMimePart *pa
 		istream = camel_stream_mem_new_with_byte_array (buffer);
 		camel_data_wrapper_decode_to_stream (
 			camel_medium_get_content ((CamelMedium *)part),
-			istream, NULL);
+			istream, NULL, NULL);
 		camel_stream_reset (istream, NULL);
 
 		dec = NSS_CMSDecoder_Start (NULL,
diff --git a/camel/camel-store.c b/camel/camel-store.c
index 8faf761..dfd598e 100644
--- a/camel/camel-store.c
+++ b/camel/camel-store.c
@@ -214,6 +214,7 @@ store_construct (CamelService *service,
 
 static CamelFolder *
 store_get_inbox (CamelStore *store,
+                 GCancellable *cancellable,
                  GError **error)
 {
 	CamelStoreClass *class;
@@ -221,7 +222,7 @@ store_get_inbox (CamelStore *store,
 
 	/* Assume the inbox's name is "inbox" and open with default flags. */
 	class = CAMEL_STORE_GET_CLASS (store);
-	folder = class->get_folder (store, "inbox", 0, error);
+	folder = class->get_folder (store, "inbox", 0, cancellable, error);
 	CAMEL_CHECK_GERROR (store, get_folder, folder != NULL, error);
 
 	return folder;
@@ -229,6 +230,7 @@ store_get_inbox (CamelStore *store,
 
 static CamelFolder *
 store_get_trash (CamelStore *store,
+                 GCancellable *cancellable,
                  GError **error)
 {
 	return store_get_special (store, CAMEL_VTRASH_FOLDER_TRASH);
@@ -236,6 +238,7 @@ store_get_trash (CamelStore *store,
 
 static CamelFolder *
 store_get_junk (CamelStore *store,
+                GCancellable *cancellable,
                 GError **error)
 {
 	return store_get_special (store, CAMEL_VTRASH_FOLDER_JUNK);
@@ -244,6 +247,7 @@ store_get_junk (CamelStore *store,
 static gboolean
 store_sync (CamelStore *store,
             gint expunge,
+            GCancellable *cancellable,
             GError **error)
 {
 	GPtrArray *folders;
@@ -263,7 +267,8 @@ store_sync (CamelStore *store,
 		folder = folders->pdata[i];
 		if (!CAMEL_IS_VEE_FOLDER (folder)
 		    && local_error == NULL) {
-			camel_folder_sync (folder, expunge, &local_error);
+			camel_folder_sync (
+				folder, expunge, cancellable, &local_error);
 			ignore_no_such_table_exception (&local_error);
 		} else if (CAMEL_IS_VEE_FOLDER (folder))
 			camel_vee_folder_sync_headers (folder, NULL); /* Literally don't care of vfolder exceptions */
@@ -282,6 +287,7 @@ store_sync (CamelStore *store,
 
 static gboolean
 store_noop (CamelStore *store,
+            GCancellable *cancellable,
             GError **error)
 {
 	return TRUE;
@@ -411,6 +417,7 @@ camel_store_error_quark (void)
  * @store: a #CamelStore object
  * @folder_name: name of the folder to get
  * @flags: folder flags (create, save body index, etc)
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Get a specific folder object from the store by name.
@@ -421,6 +428,7 @@ CamelFolder *
 camel_store_get_folder (CamelStore *store,
                         const gchar *folder_name,
                         guint32 flags,
+                        GCancellable *cancellable,
                         GError **error)
 {
 	CamelStoreClass *class;
@@ -465,14 +473,15 @@ camel_store_get_folder (CamelStore *store,
 				}
 		}
 
-		if ((store->flags & CAMEL_STORE_VTRASH) && strcmp (folder_name, CAMEL_VTRASH_NAME) == 0) {
-			folder = class->get_trash (store, error);
+		if ((store->flags & CAMEL_STORE_VTRASH) && strcmp(folder_name, CAMEL_VTRASH_NAME) == 0) {
+			folder = class->get_trash (store, cancellable, error);
 			CAMEL_CHECK_GERROR (store, get_trash, folder != NULL, error);
-		} else if ((store->flags & CAMEL_STORE_VJUNK) && strcmp (folder_name, CAMEL_VJUNK_NAME) == 0) {
-			folder = class->get_junk (store, error);
+		} else if ((store->flags & CAMEL_STORE_VJUNK) && strcmp(folder_name, CAMEL_VJUNK_NAME) == 0) {
+			folder = class->get_junk (store, cancellable, error);
 			CAMEL_CHECK_GERROR (store, get_junk, folder != NULL, error);
 		} else {
-			folder = class->get_folder (store, folder_name, flags, error);
+			folder = class->get_folder (
+				store, folder_name, flags, cancellable, error);
 			CAMEL_CHECK_GERROR (store, get_folder, folder != NULL, error);
 
 			if (folder) {
@@ -511,6 +520,7 @@ camel_store_get_folder (CamelStore *store,
  * @store: a #CamelStore object
  * @parent_name: name of the new folder's parent, or %NULL
  * @folder_name: name of the folder to create
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Creates a new folder as a child of an existing folder.
@@ -523,6 +533,7 @@ CamelFolderInfo *
 camel_store_create_folder (CamelStore *store,
                            const gchar *parent_name,
                            const gchar *folder_name,
+                           GCancellable *cancellable,
                            GError **error)
 {
 	CamelStoreClass *class;
@@ -546,8 +557,11 @@ camel_store_create_folder (CamelStore *store,
 	}
 
 	camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK);
-	fi = class->create_folder (store, parent_name, folder_name, error);
+
+	fi = class->create_folder (
+		store, parent_name, folder_name, cancellable, error);
 	CAMEL_CHECK_GERROR (store, create_folder, fi != NULL, error);
+
 	camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
 
 	return fi;
@@ -555,7 +569,8 @@ camel_store_create_folder (CamelStore *store,
 
 /* deletes folder/removes it from the folder cache, if it's there */
 static void
-cs_delete_cached_folder (CamelStore *store, const gchar *folder_name)
+cs_delete_cached_folder (CamelStore *store,
+                         const gchar *folder_name)
 {
 	CamelFolder *folder;
 
@@ -564,14 +579,14 @@ cs_delete_cached_folder (CamelStore *store, const gchar *folder_name)
 		CamelVeeFolder *vfolder;
 
 		if ((store->flags & CAMEL_STORE_VTRASH)
-		    && (vfolder = camel_object_bag_get (store->folders, CAMEL_VTRASH_NAME))) {
+		    && (vfolder = camel_object_bag_get(store->folders, CAMEL_VTRASH_NAME))) {
 			camel_vee_folder_remove_folder (vfolder, folder);
 			g_object_unref (vfolder);
 		}
 
 		if ((store->flags & CAMEL_STORE_VJUNK)
-		    && (vfolder = camel_object_bag_get (store->folders, CAMEL_VJUNK_NAME))) {
-			camel_vee_folder_remove_folder (vfolder, folder);
+		    && (vfolder = camel_object_bag_get(store->folders, CAMEL_VJUNK_NAME))) {
+			camel_vee_folder_remove_folder(vfolder, folder);
 			g_object_unref (vfolder);
 		}
 
@@ -586,6 +601,7 @@ cs_delete_cached_folder (CamelStore *store, const gchar *folder_name)
  * camel_store_delete_folder:
  * @store: a #CamelStore object
  * @folder_name: name of the folder to delete
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Deletes the named folder. The folder must be empty.
@@ -595,6 +611,7 @@ cs_delete_cached_folder (CamelStore *store, const gchar *folder_name)
 gboolean
 camel_store_delete_folder (CamelStore *store,
                            const gchar *folder_name,
+                           GCancellable *cancellable,
                            GError **error)
 {
 	CamelStoreClass *class;
@@ -620,7 +637,8 @@ camel_store_delete_folder (CamelStore *store,
 
 	camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK);
 
-	success = class->delete_folder (store, folder_name, &local_error);
+	success = class->delete_folder (
+		store, folder_name, cancellable, &local_error);
 	CAMEL_CHECK_GERROR (store, delete_folder, success, &local_error);
 
 	/* ignore 'no such table' errors */
@@ -629,7 +647,7 @@ camel_store_delete_folder (CamelStore *store,
 		g_clear_error (&local_error);
 
 	if (local_error == NULL)
-		cs_delete_cached_folder (store, folder_name);
+		cs_delete_cached_folder(store, folder_name);
 	else
 		g_propagate_error (error, local_error);
 
@@ -643,6 +661,7 @@ camel_store_delete_folder (CamelStore *store,
  * @store: a #CamelStore object
  * @old_namein: the current name of the folder
  * @new_name: the new name of the folder
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Rename a named folder to a new name.
@@ -653,6 +672,7 @@ gboolean
 camel_store_rename_folder (CamelStore *store,
                            const gchar *old_namein,
                            const gchar *new_name,
+                           GCancellable *cancellable,
                            GError **error)
 {
 	CamelStoreClass *class;
@@ -714,7 +734,8 @@ camel_store_rename_folder (CamelStore *store,
 	}
 
 	/* Now try the real rename (will emit renamed signal) */
-	success = class->rename_folder (store, old_name, new_name, error);
+	success = class->rename_folder (
+		store, old_name, new_name, cancellable, error);
 	CAMEL_CHECK_GERROR (store, rename_folder, success, error);
 
 	/* If it worked, update all open folders/unlock them */
@@ -743,7 +764,8 @@ camel_store_rename_folder (CamelStore *store,
 			if (store->flags & CAMEL_STORE_SUBSCRIPTIONS)
 				flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
 
-			folder_info = class->get_folder_info (store, new_name, flags, error);
+			folder_info = class->get_folder_info (
+				store, new_name, flags, cancellable, error);
 			CAMEL_CHECK_GERROR (store, get_folder_info, folder_info != NULL, error);
 
 			if (folder_info != NULL) {
@@ -879,6 +901,7 @@ camel_store_folder_unsubscribed (CamelStore *store,
 /**
  * camel_store_get_inbox:
  * @store: a #CamelStore object
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Returns: the folder in the store into which new mail is delivered,
@@ -886,6 +909,7 @@ camel_store_folder_unsubscribed (CamelStore *store,
  **/
 CamelFolder *
 camel_store_get_inbox (CamelStore *store,
+                       GCancellable *cancellable,
                        GError **error)
 {
 	CamelStoreClass *class;
@@ -898,7 +922,7 @@ camel_store_get_inbox (CamelStore *store,
 
 	camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK);
 
-	folder = class->get_inbox (store, error);
+	folder = class->get_inbox (store, cancellable, error);
 	CAMEL_CHECK_GERROR (store, get_inbox, folder != NULL, error);
 
 	camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
@@ -909,6 +933,7 @@ camel_store_get_inbox (CamelStore *store,
 /**
  * camel_store_get_trash:
  * @store: a #CamelStore object
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Returns: the folder in the store into which trash is delivered, or
@@ -916,6 +941,7 @@ camel_store_get_inbox (CamelStore *store,
  **/
 CamelFolder *
 camel_store_get_trash (CamelStore *store,
+                       GCancellable *cancellable,
                        GError **error)
 {
 	g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
@@ -927,18 +953,20 @@ camel_store_get_trash (CamelStore *store,
 		class = CAMEL_STORE_GET_CLASS (store);
 		g_return_val_if_fail (class->get_trash != NULL, NULL);
 
-		folder = class->get_trash (store, error);
+		folder = class->get_trash (store, cancellable, error);
 		CAMEL_CHECK_GERROR (store, get_trash, folder != NULL, error);
 
 		return folder;
 	}
 
-	return camel_store_get_folder (store, CAMEL_VTRASH_NAME, 0, error);
+	return camel_store_get_folder (
+		store, CAMEL_VTRASH_NAME, 0, cancellable, error);
 }
 
 /**
  * camel_store_get_junk:
  * @store: a #CamelStore object
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Returns: the folder in the store into which junk is delivered, or
@@ -946,6 +974,7 @@ camel_store_get_trash (CamelStore *store,
  **/
 CamelFolder *
 camel_store_get_junk (CamelStore *store,
+                      GCancellable *cancellable,
                       GError **error)
 {
 	g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
@@ -957,19 +986,21 @@ camel_store_get_junk (CamelStore *store,
 		class = CAMEL_STORE_GET_CLASS (store);
 		g_return_val_if_fail (class->get_junk != NULL, NULL);
 
-		folder = class->get_junk (store, error);
+		folder = class->get_junk (store, cancellable, error);
 		CAMEL_CHECK_GERROR (store, get_junk, folder != NULL, error);
 
 		return folder;
 	}
 
-	return camel_store_get_folder (store, CAMEL_VJUNK_NAME, 0, error);
+	return camel_store_get_folder (
+		store, CAMEL_VJUNK_NAME, 0, cancellable, error);
 }
 
 /**
  * camel_store_sync:
  * @store: a #CamelStore object
  * @expunge: %TRUE if an expunge should be done after sync or %FALSE otherwise
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Syncs any changes that have been made to the store object and its
@@ -980,6 +1011,7 @@ camel_store_get_junk (CamelStore *store,
 gboolean
 camel_store_sync (CamelStore *store,
                   gint expunge,
+                  GCancellable *cancellable,
                   GError **error)
 {
 	CamelStoreClass *class;
@@ -990,7 +1022,7 @@ camel_store_sync (CamelStore *store,
 	class = CAMEL_STORE_GET_CLASS (store);
 	g_return_val_if_fail (class->sync != NULL, FALSE);
 
-	success = class->sync (store, expunge, error);
+	success = class->sync (store, expunge, cancellable, error);
 	CAMEL_CHECK_GERROR (store, sync, success, error);
 
 	return success;
@@ -1081,20 +1113,21 @@ dump_fi (CamelFolderInfo *fi, gint depth)
  * @store: a #CamelStore object
  * @top: the name of the folder to start from
  * @flags: various CAMEL_STORE_FOLDER_INFO_* flags to control behavior
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * This fetches information about the folder structure of @store,
  * starting with @top, and returns a tree of CamelFolderInfo
- * structures. If @flags includes #CAMEL_STORE_FOLDER_INFO_SUBSCRIBED,
+ * structures. If @flags includes %CAMEL_STORE_FOLDER_INFO_SUBSCRIBED,
  * only subscribed folders will be listed.   If the store doesn't support
  * subscriptions, then it will list all folders.  If @flags includes
- * #CAMEL_STORE_FOLDER_INFO_RECURSIVE, the returned tree will include
+ * %CAMEL_STORE_FOLDER_INFO_RECURSIVE, the returned tree will include
  * all levels of hierarchy below @top. If not, it will only include
  * the immediate subfolders of @top. If @flags includes
- * #CAMEL_STORE_FOLDER_INFO_FAST, the unread_message_count fields of
+ * %CAMEL_STORE_FOLDER_INFO_FAST, the unread_message_count fields of
  * some or all of the structures may be set to %-1, if the store cannot
  * determine that information quickly.  If @flags includes
- * #CAMEL_STORE_FOLDER_INFO_NO_VIRTUAL, don't include special virtual
+ * %CAMEL_STORE_FOLDER_INFO_NO_VIRTUAL, don't include special virtual
  * folders (such as vTrash or vJunk).
  *
  * The CAMEL_STORE_FOLDER_INFO_FAST flag should be considered
@@ -1109,6 +1142,7 @@ CamelFolderInfo *
 camel_store_get_folder_info (CamelStore *store,
                              const gchar *top,
                              guint32 flags,
+                             GCancellable *cancellable,
                              GError **error)
 {
 	CamelStoreClass *class;
@@ -1119,7 +1153,7 @@ camel_store_get_folder_info (CamelStore *store,
 	class = CAMEL_STORE_GET_CLASS (store);
 	g_return_val_if_fail (class->get_folder_info != NULL, NULL);
 
-	info = class->get_folder_info (store, top, flags, error);
+	info = class->get_folder_info (store, top, flags, cancellable, error);
 	if (!(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED))
 		CAMEL_CHECK_GERROR (store, get_folder_info, info != NULL, error);
 
@@ -1461,6 +1495,7 @@ camel_store_folder_is_subscribed (CamelStore *store,
  * camel_store_subscribe_folder:
  * @store: a #CamelStore object
  * @folder_name: full path of the folder
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Subscribe to the folder described by @folder_name.
@@ -1470,6 +1505,7 @@ camel_store_folder_is_subscribed (CamelStore *store,
 gboolean
 camel_store_subscribe_folder (CamelStore *store,
                               const gchar *folder_name,
+                              GCancellable *cancellable,
                               GError **error)
 {
 	CamelStoreClass *class;
@@ -1484,7 +1520,8 @@ camel_store_subscribe_folder (CamelStore *store,
 
 	camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK);
 
-	success = class->subscribe_folder (store, folder_name, error);
+	success = class->subscribe_folder (
+		store, folder_name, cancellable, error);
 	CAMEL_CHECK_GERROR (store, subscribe_folder, success, error);
 
 	camel_store_unlock (store, CAMEL_STORE_FOLDER_LOCK);
@@ -1496,6 +1533,7 @@ camel_store_subscribe_folder (CamelStore *store,
  * camel_store_unsubscribe_folder:
  * @store: a #CamelStore object
  * @folder_name: full path of the folder
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Unsubscribe from the folder described by @folder_name.
@@ -1505,6 +1543,7 @@ camel_store_subscribe_folder (CamelStore *store,
 gboolean
 camel_store_unsubscribe_folder (CamelStore *store,
                                 const gchar *folder_name,
+                                GCancellable *cancellable,
                                 GError **error)
 {
 	CamelStoreClass *class;
@@ -1519,7 +1558,8 @@ camel_store_unsubscribe_folder (CamelStore *store,
 
 	camel_store_lock (store, CAMEL_STORE_FOLDER_LOCK);
 
-	success = class->unsubscribe_folder (store, folder_name, error);
+	success = class->unsubscribe_folder (
+		store, folder_name, cancellable, error);
 	CAMEL_CHECK_GERROR (store, unsubscribe_folder, success, error);
 
 	if (success)
@@ -1533,6 +1573,7 @@ camel_store_unsubscribe_folder (CamelStore *store,
 /**
  * camel_store_noop:
  * @store: a #CamelStore object
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Pings @store so that its connection doesn't timeout.
@@ -1541,6 +1582,7 @@ camel_store_unsubscribe_folder (CamelStore *store,
  **/
 gboolean
 camel_store_noop (CamelStore *store,
+                  GCancellable *cancellable,
                   GError **error)
 {
 	CamelStoreClass *class;
@@ -1551,7 +1593,7 @@ camel_store_noop (CamelStore *store,
 	class = CAMEL_STORE_GET_CLASS (store);
 	g_return_val_if_fail (class->noop != NULL, FALSE);
 
-	success = class->noop (store, error);
+	success = class->noop (store, cancellable, error);
 	CAMEL_CHECK_GERROR (store, noop, success, error);
 
 	return success;
diff --git a/camel/camel-store.h b/camel/camel-store.h
index 2ad2c9d..1d75b6a 100644
--- a/camel/camel-store.h
+++ b/camel/camel-store.h
@@ -224,32 +224,41 @@ struct _CamelStoreClass {
 	CamelFolder *	(*get_folder)		(CamelStore *store,
 						 const gchar *folder_name,
 						 guint32 flags,
+						 GCancellable *cancellable,
 						 GError **error);
 	CamelFolder *	(*get_inbox)		(CamelStore *store,
+						 GCancellable *cancellable,
 						 GError **error);
 	CamelFolder *	(*get_trash)		(CamelStore *store,
+						 GCancellable *cancellable,
 						 GError **error);
 	CamelFolder *	(*get_junk)		(CamelStore *store,
+						 GCancellable *cancellable,
 						 GError **error);
 	CamelFolderInfo *
 			(*create_folder)	(CamelStore *store,
 						 const gchar *parent_name,
 						 const gchar *folder_name,
+						 GCancellable *cancellable,
 						 GError **error);
 	gboolean	(*delete_folder)	(CamelStore *store,
 						 const gchar *folder_name,
+						 GCancellable *cancellable,
 						 GError **error);
 	gboolean	(*rename_folder)	(CamelStore *store,
 						 const gchar *old_name,
 						 const gchar *new_name,
+						 GCancellable *cancellable,
 						 GError **error);
 	gboolean	(*sync)			(CamelStore *store,
 						 gint expunge,
+						 GCancellable *cancellable,
 						 GError **error);
 	CamelFolderInfo *
 			(*get_folder_info)	(CamelStore *store,
 						 const gchar *top,
 						 guint32 flags,
+						 GCancellable *cancellable,
 						 GError **error);
 	void		(*free_folder_info)	(CamelStore *store,
 						 CamelFolderInfo *fi);
@@ -257,11 +266,14 @@ struct _CamelStoreClass {
 						 const gchar *folder_name);
 	gboolean	(*subscribe_folder)	(CamelStore *store,
 						 const gchar *folder_name,
+						 GCancellable *cancellable,
 						 GError **error);
 	gboolean	(*unsubscribe_folder)	(CamelStore *store,
 						 const gchar *folder_name,
+						 GCancellable *cancellable,
 						 GError **error);
 	gboolean	(*noop)			(CamelStore *store,
+						 GCancellable *cancellable,
 						 GError **error);
 	gboolean	(*can_refresh_folder)	(CamelStore *store,
 						 CamelFolderInfo *info,
@@ -288,24 +300,31 @@ GQuark		camel_store_error_quark		(void) G_GNUC_CONST;
 CamelFolder *	camel_store_get_folder		(CamelStore *store,
 						 const gchar *folder_name,
 						 guint32 flags,
+						 GCancellable *cancellable,
 						 GError **error);
 CamelFolder *	camel_store_get_inbox		(CamelStore *store,
+						 GCancellable *cancellable,
 						 GError **error);
 CamelFolder *	camel_store_get_trash		(CamelStore *store,
+						 GCancellable *cancellable,
 						 GError **error);
 CamelFolder *	camel_store_get_junk		(CamelStore *store,
+						 GCancellable *cancellable,
 						 GError **error);
 CamelFolderInfo *
 		camel_store_create_folder	(CamelStore *store,
 						 const gchar *parent_name,
 						 const gchar *folder_name,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_store_delete_folder	(CamelStore *store,
 						 const gchar *folder_name,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_store_rename_folder	(CamelStore *store,
 						 const gchar *old_namein,
 						 const gchar *new_name,
+						 GCancellable *cancellable,
 						 GError **error);
 void		camel_store_folder_created	(CamelStore *store,
 						 CamelFolderInfo *info);
@@ -320,11 +339,13 @@ void		camel_store_folder_unsubscribed	(CamelStore *store,
 						 CamelFolderInfo *info);
 gboolean	camel_store_sync		(CamelStore *store,
 						 gint expunge,
+						 GCancellable *cancellable,
 						 GError **error);
 CamelFolderInfo *
 		camel_store_get_folder_info	(CamelStore *store,
 						 const gchar *top,
 						 guint32 flags,
+						 GCancellable *cancellable,
 						 GError **error);
 void		camel_store_free_folder_info	(CamelStore *store,
 						 CamelFolderInfo *fi);
@@ -351,11 +372,14 @@ gboolean	camel_store_folder_is_subscribed (CamelStore *store,
 						 const gchar *folder_name);
 gboolean	camel_store_subscribe_folder	(CamelStore *store,
 						 const gchar *folder_name,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_store_unsubscribe_folder	(CamelStore *store,
 						 const gchar *folder_name,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_store_noop		(CamelStore *store,
+						 GCancellable *cancellable,
 						 GError **error);
 gint		camel_store_folder_uri_equal	(CamelStore *store,
 						 const gchar *uri0,
diff --git a/camel/camel-stream-buffer.c b/camel/camel-stream-buffer.c
index 7448fe4..1b858b5 100644
--- a/camel/camel-stream-buffer.c
+++ b/camel/camel-stream-buffer.c
@@ -64,12 +64,14 @@ static gssize
 stream_write_all (CamelStream *stream,
                   const gchar *buffer,
                   gsize n,
+                  GCancellable *cancellable,
                   GError **error)
 {
 	gsize left = n, w;
 
 	while (left > 0) {
-		w = camel_stream_write (stream, buffer, left, error);
+		w = camel_stream_write (
+			stream, buffer, left, cancellable, error);
 		if (w == -1)
 			return -1;
 		left -= w;
@@ -142,6 +144,7 @@ static gssize
 stream_buffer_read (CamelStream *stream,
                     gchar *buffer,
                     gsize n,
+                    GCancellable *cancellable,
                     GError **error)
 {
 	CamelStreamBufferPrivate *priv;
@@ -168,15 +171,16 @@ stream_buffer_read (CamelStream *stream,
 			/* if we are reading a lot, then read directly to the destination buffer */
 			if (n >= priv->size/3) {
 				bytes_read = camel_stream_read (
-					priv->stream, bptr, n, &local_error);
+					priv->stream, bptr, n,
+					cancellable, &local_error);
 				if (bytes_read>0) {
 					n -= bytes_read;
 					bptr += bytes_read;
 				}
 			} else {
 				bytes_read = camel_stream_read (
-					priv->stream, (gchar *)
-					priv->buf, priv->size, &local_error);
+					priv->stream, (gchar *) priv->buf,
+					priv->size, cancellable, &local_error);
 				if (bytes_read>0) {
 					gsize bytes_used = bytes_read > n ? n : bytes_read;
 					priv->ptr = priv->buf;
@@ -214,6 +218,7 @@ static gssize
 stream_buffer_write (CamelStream *stream,
                      const gchar *buffer,
                      gsize n,
+                     GCancellable *cancellable,
                      GError **error)
 {
 	CamelStreamBufferPrivate *priv;
@@ -239,7 +244,7 @@ stream_buffer_write (CamelStream *stream,
 	if (left == todo) {
 		if (stream_write_all (
 			priv->stream, (gchar *) priv->buf,
-			priv->size, error) == -1)
+			priv->size, cancellable, error) == -1)
 			return -1;
 
 		priv->ptr = priv->buf;
@@ -249,7 +254,8 @@ stream_buffer_write (CamelStream *stream,
 	if (n > 0) {
 		if (n >= priv->size/3) {
 			if (stream_write_all (
-				priv->stream, buffer, n, error) == -1)
+				priv->stream, buffer, n,
+				cancellable, error) == -1)
 				return -1;
 		} else {
 			memcpy (priv->ptr, buffer, n);
@@ -262,6 +268,7 @@ stream_buffer_write (CamelStream *stream,
 
 static gint
 stream_buffer_flush (CamelStream *stream,
+                     GCancellable *cancellable,
                      GError **error)
 {
 	CamelStreamBufferPrivate *priv;
@@ -272,7 +279,8 @@ stream_buffer_flush (CamelStream *stream,
 		gsize len = priv->ptr - priv->buf;
 
 		if (camel_stream_write (
-			priv->stream, (gchar *) priv->buf, len, error) == -1)
+			priv->stream, (gchar *) priv->buf,
+			len, cancellable, error) == -1)
 			return -1;
 
 		priv->ptr = priv->buf;
@@ -280,21 +288,22 @@ stream_buffer_flush (CamelStream *stream,
 		/* nothing to do for read mode 'flush' */
 	}
 
-	return camel_stream_flush (priv->stream, error);
+	return camel_stream_flush (priv->stream, cancellable, error);
 }
 
 static gint
 stream_buffer_close (CamelStream *stream,
+                     GCancellable *cancellable,
                      GError **error)
 {
 	CamelStreamBufferPrivate *priv;
 
 	priv = CAMEL_STREAM_BUFFER_GET_PRIVATE (stream);
 
-	if (stream_buffer_flush (stream, error) == -1)
+	if (stream_buffer_flush (stream, cancellable, error) == -1)
 		return -1;
 
-	return camel_stream_close (priv->stream, error);
+	return camel_stream_close (priv->stream, cancellable, error);
 }
 
 static gboolean
@@ -470,6 +479,7 @@ camel_stream_buffer_new_with_vbuf (CamelStream *stream,
  * @sbf: a #CamelStreamBuffer object
  * @buf: Memory to write the string to.
  * @max: Maxmimum number of characters to store.
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Read a line of characters up to the next newline character or
@@ -485,6 +495,7 @@ gint
 camel_stream_buffer_gets (CamelStreamBuffer *sbf,
                           gchar *buf,
                           guint max,
+                          GCancellable *cancellable,
                           GError **error)
 {
 	register gchar *outptr, *inptr, *inend, c, *outend;
@@ -509,8 +520,8 @@ camel_stream_buffer_gets (CamelStreamBuffer *sbf,
 			break;
 
 		bytes_read = camel_stream_read (
-			sbf->priv->stream, (gchar *)
-			sbf->priv->buf, sbf->priv->size, error);
+			sbf->priv->stream, (gchar *) sbf->priv->buf,
+			sbf->priv->size, cancellable, error);
 		if (bytes_read == -1) {
 			if (buf == outptr)
 				return -1;
@@ -532,6 +543,7 @@ camel_stream_buffer_gets (CamelStreamBuffer *sbf,
 /**
  * camel_stream_buffer_read_line:
  * @sbf: a #CamelStreamBuffer object
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a @GError, or %NULL
  *
  * This function reads a complete newline-terminated line from the stream
@@ -543,6 +555,7 @@ camel_stream_buffer_gets (CamelStreamBuffer *sbf,
  **/
 gchar *
 camel_stream_buffer_read_line (CamelStreamBuffer *sbf,
+                               GCancellable *cancellable,
                                GError **error)
 {
 	guchar *p;
@@ -553,7 +566,7 @@ camel_stream_buffer_read_line (CamelStreamBuffer *sbf,
 	while (1) {
 		nread = camel_stream_buffer_gets (
 			sbf, (gchar *) p, sbf->priv->linesize -
-			(p - sbf->priv->linebuf), error);
+			(p - sbf->priv->linebuf), cancellable, error);
 		if (nread <=0) {
 			if (p > sbf->priv->linebuf)
 				break;
diff --git a/camel/camel-stream-buffer.h b/camel/camel-stream-buffer.h
index c1d82d6..62c23a7 100644
--- a/camel/camel-stream-buffer.h
+++ b/camel/camel-stream-buffer.h
@@ -95,8 +95,10 @@ CamelStream *	camel_stream_buffer_new_with_vbuf
 gint		camel_stream_buffer_gets	(CamelStreamBuffer *sbf,
 						 gchar *buf,
 						 guint max,
+						 GCancellable *cancellable,
 						 GError **error);
 gchar *		camel_stream_buffer_read_line	(CamelStreamBuffer *sbf,
+						 GCancellable *cancellable,
 						 GError **error);
 
 G_END_DECLS
diff --git a/camel/camel-stream-filter.c b/camel/camel-stream-filter.c
index e282323..0a67e8d 100644
--- a/camel/camel-stream-filter.c
+++ b/camel/camel-stream-filter.c
@@ -92,6 +92,7 @@ static gssize
 stream_filter_read (CamelStream *stream,
                     gchar *buffer,
                     gsize n,
+                    GCancellable *cancellable,
                     GError **error)
 {
 	CamelStreamFilterPrivate *priv;
@@ -108,7 +109,8 @@ stream_filter_read (CamelStream *stream,
 		gsize presize = READ_PAD;
 
 		size = camel_stream_read (
-			priv->source, priv->buffer, READ_SIZE, error);
+			priv->source, priv->buffer,
+			READ_SIZE, cancellable, error);
 		if (size <= 0) {
 			/* this is somewhat untested */
 			if (camel_stream_eos (priv->source)) {
@@ -168,6 +170,7 @@ static gssize
 stream_filter_write (CamelStream *stream,
                      const gchar *buf,
                      gsize n,
+                     GCancellable *cancellable,
                      GError **error)
 {
 	CamelStreamFilterPrivate *priv;
@@ -207,7 +210,7 @@ stream_filter_write (CamelStream *stream,
 			f = f->next;
 		}
 
-		if (camel_stream_write (priv->source, buffer, len, error) != len)
+		if (camel_stream_write (priv->source, buffer, len, cancellable, error) != len)
 			return -1;
 	}
 
@@ -218,6 +221,7 @@ stream_filter_write (CamelStream *stream,
 
 static gint
 stream_filter_flush (CamelStream *stream,
+                     GCancellable *cancellable,
                      GError **error)
 {
 	CamelStreamFilterPrivate *priv;
@@ -250,14 +254,15 @@ stream_filter_flush (CamelStream *stream,
 		f = f->next;
 	}
 
-	if (len > 0 && camel_stream_write (priv->source, buffer, len, error) == -1)
+	if (len > 0 && camel_stream_write (priv->source, buffer, len, cancellable, error) == -1)
 		return -1;
 
-	return camel_stream_flush (priv->source, error);
+	return camel_stream_flush (priv->source, cancellable, error);
 }
 
 static gint
 stream_filter_close (CamelStream *stream,
+                     GCancellable *cancellable,
                      GError **error)
 {
 	CamelStreamFilterPrivate *priv;
@@ -266,9 +271,9 @@ stream_filter_close (CamelStream *stream,
 
 	/* Ignore errors while flushing. */
 	if (!priv->last_was_read)
-		stream_filter_flush (stream, NULL);
+		stream_filter_flush (stream, cancellable, NULL);
 
-	return camel_stream_close (priv->source, error);
+	return camel_stream_close (priv->source, cancellable, error);
 }
 
 static gboolean
diff --git a/camel/camel-stream-fs.c b/camel/camel-stream-fs.c
index cea4758..1c577c7 100644
--- a/camel/camel-stream-fs.c
+++ b/camel/camel-stream-fs.c
@@ -67,6 +67,7 @@ static gssize
 stream_fs_read (CamelStream *stream,
                 gchar *buffer,
                 gsize n,
+                GCancellable *cancellable,
                 GError **error)
 {
 	CamelStreamFsPrivate *priv;
@@ -79,7 +80,9 @@ stream_fs_read (CamelStream *stream,
 	if (seekable->bound_end != CAMEL_STREAM_UNBOUND)
 		n = MIN (seekable->bound_end - seekable->position, n);
 
-	if ((nread = camel_read (priv->fd, buffer, n, error)) > 0)
+	nread = camel_read (priv->fd, buffer, n, cancellable, error);
+
+	if (nread > 0)
 		seekable->position += nread;
 	else if (nread == 0)
 		stream->eos = TRUE;
@@ -91,6 +94,7 @@ static gssize
 stream_fs_write (CamelStream *stream,
                  const gchar *buffer,
                  gsize n,
+                 GCancellable *cancellable,
                  GError **error)
 {
 	CamelStreamFsPrivate *priv;
@@ -103,7 +107,9 @@ stream_fs_write (CamelStream *stream,
 	if (seekable->bound_end != CAMEL_STREAM_UNBOUND)
 		n = MIN (seekable->bound_end - seekable->position, n);
 
-	if ((nwritten = camel_write (priv->fd, buffer, n, error)) > 0)
+	nwritten = camel_write (priv->fd, buffer, n, cancellable, error);
+
+	if (nwritten > 0)
 		seekable->position += nwritten;
 
 	return nwritten;
@@ -111,6 +117,7 @@ stream_fs_write (CamelStream *stream,
 
 static gint
 stream_fs_flush (CamelStream *stream,
+                 GCancellable *cancellable,
                  GError **error)
 {
 	CamelStreamFsPrivate *priv;
@@ -130,6 +137,7 @@ stream_fs_flush (CamelStream *stream,
 
 static gint
 stream_fs_close (CamelStream *stream,
+                 GCancellable *cancellable,
                  GError **error)
 {
 	CamelStreamFsPrivate *priv;
diff --git a/camel/camel-stream-mem.c b/camel/camel-stream-mem.c
index 1649fe4..4ac97dd 100644
--- a/camel/camel-stream-mem.c
+++ b/camel/camel-stream-mem.c
@@ -89,6 +89,7 @@ static gssize
 stream_mem_read (CamelStream *stream,
                  gchar *buffer,
                  gsize n,
+                 GCancellable *cancellable,
                  GError **error)
 {
 	CamelStreamMemPrivate *priv;
@@ -114,6 +115,7 @@ static gssize
 stream_mem_write (CamelStream *stream,
                   const gchar *buffer,
                   gsize n,
+                  GCancellable *cancellable,
                   GError **error)
 {
 	CamelStreamMemPrivate *priv;
diff --git a/camel/camel-stream-null.c b/camel/camel-stream-null.c
index 0050744..6e208a6 100644
--- a/camel/camel-stream-null.c
+++ b/camel/camel-stream-null.c
@@ -34,6 +34,7 @@ static gssize
 stream_null_write (CamelStream *stream,
                    const gchar *buffer,
                    gsize n,
+                   GCancellable *cancellable,
                    GError **error)
 {
 	CAMEL_STREAM_NULL (stream)->written += n;
diff --git a/camel/camel-stream-process.c b/camel/camel-stream-process.c
index b4880ba..2f699da 100644
--- a/camel/camel-stream-process.c
+++ b/camel/camel-stream-process.c
@@ -51,7 +51,7 @@ stream_process_finalize (GObject *object)
 {
 	/* Ensure we clean up after ourselves -- kill
 	   the child process and reap it. */
-	camel_stream_close (CAMEL_STREAM (object), NULL);
+	camel_stream_close (CAMEL_STREAM (object), NULL, NULL);
 
 	/* Chain up to parent's finalize() method. */
 	G_OBJECT_CLASS (camel_stream_process_parent_class)->finalize (object);
@@ -61,26 +61,31 @@ static gssize
 stream_process_read (CamelStream *stream,
                      gchar *buffer,
                      gsize n,
+                     GCancellable *cancellable,
                      GError **error)
 {
 	CamelStreamProcess *stream_process = CAMEL_STREAM_PROCESS (stream);
+	gint fd = stream_process->sockfd;
 
-	return camel_read (stream_process->sockfd, buffer, n, error);
+	return camel_read (fd, buffer, n, cancellable, error);
 }
 
 static gssize
 stream_process_write (CamelStream *stream,
                       const gchar *buffer,
                       gsize n,
+                      GCancellable *cancellable,
                       GError **error)
 {
 	CamelStreamProcess *stream_process = CAMEL_STREAM_PROCESS (stream);
+	gint fd = stream_process->sockfd;
 
-	return camel_write (stream_process->sockfd, buffer, n, error);
+	return camel_write (fd, buffer, n, cancellable, error);
 }
 
 static gint
 stream_process_close (CamelStream *object,
+                      GCancellable *cancellable,
                       GError **error)
 {
 	CamelStreamProcess *stream = CAMEL_STREAM_PROCESS (object);
@@ -131,6 +136,7 @@ stream_process_close (CamelStream *object,
 
 static gint
 stream_process_flush (CamelStream *stream,
+                      GCancellable *cancellable,
                       GError **error)
 {
 	return 0;
@@ -228,7 +234,7 @@ camel_stream_process_connect (CamelStreamProcess *stream,
 	g_return_val_if_fail (command != NULL, -1);
 
 	if (stream->sockfd != -1 || stream->childpid)
-		camel_stream_close (CAMEL_STREAM (stream), NULL);
+		camel_stream_close (CAMEL_STREAM (stream), NULL, NULL);
 
 	if (socketpair (AF_UNIX, SOCK_STREAM, 0, sockfds))
 		return -1;
diff --git a/camel/camel-stream-vfs.c b/camel/camel-stream-vfs.c
index eb46c13..0c2dc69 100644
--- a/camel/camel-stream-vfs.c
+++ b/camel/camel-stream-vfs.c
@@ -54,6 +54,7 @@ static gssize
 stream_vfs_read (CamelStream *stream,
                  gchar *buffer,
                  gsize n,
+                 GCancellable *cancellable,
                  GError **error)
 {
 	CamelStreamVFS *stream_vfs = CAMEL_STREAM_VFS (stream);
@@ -62,7 +63,7 @@ stream_vfs_read (CamelStream *stream,
 
 	nread = g_input_stream_read (
 		G_INPUT_STREAM (stream_vfs->stream),
-		buffer, n, NULL, &local_error);
+		buffer, n, cancellable, &local_error);
 
 	if (nread == 0 || local_error != NULL)
 		stream->eos = TRUE;
@@ -77,6 +78,7 @@ static gssize
 stream_vfs_write (CamelStream *stream,
                   const gchar *buffer,
                   gsize n,
+                  GCancellable *cancellable,
                   GError **error)
 {
 	CamelStreamVFS *stream_vfs = CAMEL_STREAM_VFS (stream);
@@ -85,26 +87,28 @@ stream_vfs_write (CamelStream *stream,
 
 	success = g_output_stream_write_all (
 		G_OUTPUT_STREAM (stream_vfs->stream),
-		buffer, n, &bytes_written, NULL, error);
+		buffer, n, &bytes_written, cancellable, error);
 
 	return success ? bytes_written : -1;
 }
 
 static gint
 stream_vfs_flush (CamelStream *stream,
+                  GCancellable *cancellable,
                   GError **error)
 {
 	CamelStreamVFS *stream_vfs = CAMEL_STREAM_VFS (stream);
 	gboolean success;
 
 	success = g_output_stream_flush (
-		G_OUTPUT_STREAM (stream_vfs->stream), NULL, error);
+		G_OUTPUT_STREAM (stream_vfs->stream), cancellable, error);
 
 	return success ? 0 : -1;
 }
 
 static gint
 stream_vfs_close (CamelStream *stream,
+                  GCancellable *cancellable,
                   GError **error)
 {
 	CamelStreamVFS *stream_vfs = CAMEL_STREAM_VFS (stream);
@@ -112,10 +116,12 @@ stream_vfs_close (CamelStream *stream,
 
 	if (G_IS_OUTPUT_STREAM (stream_vfs->stream))
 		success = g_output_stream_close (
-			G_OUTPUT_STREAM (stream_vfs->stream), NULL, error);
+			G_OUTPUT_STREAM (stream_vfs->stream),
+			cancellable, error);
 	else
 		success = g_input_stream_close (
-			G_INPUT_STREAM (stream_vfs->stream), NULL, error);
+			G_INPUT_STREAM (stream_vfs->stream),
+			cancellable, error);
 
 	if (success) {
 		g_object_unref (stream_vfs->stream);
diff --git a/camel/camel-stream.c b/camel/camel-stream.c
index 38848b4..c649b26 100644
--- a/camel/camel-stream.c
+++ b/camel/camel-stream.c
@@ -38,6 +38,7 @@ static gssize
 stream_read (CamelStream *stream,
              gchar *buffer,
              gsize n,
+             GCancellable *cancellable,
              GError **error)
 {
 	return 0;
@@ -47,6 +48,7 @@ static gssize
 stream_write (CamelStream *stream,
               const gchar *buffer,
               gsize n,
+              GCancellable *cancellable,
               GError **error)
 {
 	return n;
@@ -54,6 +56,7 @@ stream_write (CamelStream *stream,
 
 static gint
 stream_close (CamelStream *stream,
+              GCancellable *cancellable,
               GError **error)
 {
 	return 0;
@@ -61,6 +64,7 @@ stream_close (CamelStream *stream,
 
 static gint
 stream_flush (CamelStream *stream,
+              GCancellable *cancellable,
               GError **error)
 {
 	return 0;
@@ -100,6 +104,7 @@ camel_stream_init (CamelStream *stream)
  * @stream: a #CamelStream object.
  * @buffer: output buffer
  * @n: max number of bytes to read.
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Attempts to read up to @len bytes from @stream into @buf.
@@ -111,6 +116,7 @@ gssize
 camel_stream_read (CamelStream *stream,
                    gchar *buffer,
                    gsize n,
+                   GCancellable *cancellable,
                    GError **error)
 {
 	CamelStreamClass *class;
@@ -122,7 +128,7 @@ camel_stream_read (CamelStream *stream,
 	class = CAMEL_STREAM_GET_CLASS (stream);
 	g_return_val_if_fail (class->read != NULL, -1);
 
-	n_bytes = class->read (stream, buffer, n, error);
+	n_bytes = class->read (stream, buffer, n, cancellable, error);
 	CAMEL_CHECK_GERROR (stream, read, n_bytes >= 0, error);
 
 	return n_bytes;
@@ -133,6 +139,7 @@ camel_stream_read (CamelStream *stream,
  * @stream: a #CamelStream object
  * @buffer: buffer to write.
  * @n: number of bytes to write
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Attempts to write up to @n bytes of @buffer into @stream.
@@ -144,6 +151,7 @@ gssize
 camel_stream_write (CamelStream *stream,
                     const gchar *buffer,
                     gsize n,
+                    GCancellable *cancellable,
                     GError **error)
 {
 	CamelStreamClass *class;
@@ -155,7 +163,7 @@ camel_stream_write (CamelStream *stream,
 	class = CAMEL_STREAM_GET_CLASS (stream);
 	g_return_val_if_fail (class->write != NULL, -1);
 
-	n_bytes = class->write (stream, buffer, n, error);
+	n_bytes = class->write (stream, buffer, n, cancellable, error);
 	CAMEL_CHECK_GERROR (stream, write, n_bytes >= 0, error);
 
 	return n_bytes;
@@ -164,6 +172,7 @@ camel_stream_write (CamelStream *stream,
 /**
  * camel_stream_flush:
  * @stream: a #CamelStream object
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Flushes any buffered data to the stream's backing store.  Only
@@ -173,6 +182,7 @@ camel_stream_write (CamelStream *stream,
  **/
 gint
 camel_stream_flush (CamelStream *stream,
+                    GCancellable *cancellable,
                     GError **error)
 {
 	CamelStreamClass *class;
@@ -183,7 +193,7 @@ camel_stream_flush (CamelStream *stream,
 	class = CAMEL_STREAM_GET_CLASS (stream);
 	g_return_val_if_fail (class->flush != NULL, -1);
 
-	retval = class->flush (stream, error);
+	retval = class->flush (stream, cancellable, error);
 	CAMEL_CHECK_GERROR (stream, flush, retval == 0, error);
 
 	return retval;
@@ -192,6 +202,7 @@ camel_stream_flush (CamelStream *stream,
 /**
  * camel_stream_close:
  * @stream: a #CamelStream object
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Closes the stream.
@@ -200,6 +211,7 @@ camel_stream_flush (CamelStream *stream,
  **/
 gint
 camel_stream_close (CamelStream *stream,
+                    GCancellable *cancellable,
                     GError **error)
 {
 	CamelStreamClass *class;
@@ -210,7 +222,7 @@ camel_stream_close (CamelStream *stream,
 	class = CAMEL_STREAM_GET_CLASS (stream);
 	g_return_val_if_fail (class->close != NULL, -1);
 
-	retval = class->close (stream, error);
+	retval = class->close (stream, cancellable, error);
 	CAMEL_CHECK_GERROR (stream, close, retval == 0, error);
 
 	return retval;
@@ -281,12 +293,14 @@ camel_stream_reset (CamelStream *stream,
 gssize
 camel_stream_write_string (CamelStream *stream,
                            const gchar *string,
+                           GCancellable *cancellable,
                            GError **error)
 {
 	g_return_val_if_fail (CAMEL_IS_STREAM (stream), -1);
 	g_return_val_if_fail (string != NULL, -1);
 
-	return camel_stream_write (stream, string, strlen (string), error);
+	return camel_stream_write (
+		stream, string, strlen (string), cancellable, error);
 }
 
 /**
@@ -307,6 +321,9 @@ camel_stream_printf (CamelStream *stream,
 	gchar *string;
 	gssize ret;
 
+	/* XXX This function needs to die.  Use a GString to
+	 *     assemble formatted output. */
+
 	g_return_val_if_fail (CAMEL_IS_STREAM (stream), -1);
 
 	va_start (args, fmt);
@@ -316,7 +333,8 @@ camel_stream_printf (CamelStream *stream,
 	if (string == NULL)
 		return -1;
 
-	ret = camel_stream_write (stream, string, strlen (string), NULL);
+	ret = camel_stream_write (
+		stream, string, strlen (string), NULL, NULL);
 	g_free (string);
 
 	return ret;
@@ -326,6 +344,7 @@ camel_stream_printf (CamelStream *stream,
  * camel_stream_write_to_stream:
  * @stream: source #CamelStream object
  * @output_stream: destination #CamelStream object
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Write all of a stream (until eos) into another stream, in a
@@ -337,6 +356,7 @@ camel_stream_printf (CamelStream *stream,
 gssize
 camel_stream_write_to_stream (CamelStream *stream,
                               CamelStream *output_stream,
+                              GCancellable *cancellable,
                               GError **error)
 {
 	gchar tmp_buf[4096];
@@ -349,7 +369,8 @@ camel_stream_write_to_stream (CamelStream *stream,
 
 	while (!camel_stream_eos (stream)) {
 		nb_read = camel_stream_read (
-			stream, tmp_buf, sizeof (tmp_buf), error);
+			stream, tmp_buf, sizeof (tmp_buf),
+			cancellable, error);
 		if (nb_read < 0)
 			return -1;
 		else if (nb_read > 0) {
@@ -357,8 +378,10 @@ camel_stream_write_to_stream (CamelStream *stream,
 
 			while (nb_written < nb_read) {
 				gssize len = camel_stream_write (
-					output_stream, tmp_buf + nb_written,
-					nb_read - nb_written, error);
+					output_stream,
+					tmp_buf + nb_written,
+					nb_read - nb_written,
+					cancellable, error);
 				if (len < 0)
 					return -1;
 				nb_written += len;
diff --git a/camel/camel-stream.h b/camel/camel-stream.h
index 3dac147..6b88919 100644
--- a/camel/camel-stream.h
+++ b/camel/camel-stream.h
@@ -69,14 +69,18 @@ struct _CamelStreamClass {
 	gssize		(*read)			(CamelStream *stream,
 						 gchar *buffer,
 						 gsize n,
+						 GCancellable *cancellable,
 						 GError **error);
 	gssize		(*write)		(CamelStream *stream,
 						 const gchar *buffer,
 						 gsize n,
+						 GCancellable *cancellable,
 						 GError **error);
 	gint		(*close)		(CamelStream *stream,
+						 GCancellable *cancellable,
 						 GError **error);
 	gint		(*flush)		(CamelStream *stream,
+						 GCancellable *cancellable,
 						 GError **error);
 	gboolean	(*eos)			(CamelStream *stream);
 	gint		(*reset)		(CamelStream *stream,
@@ -87,14 +91,18 @@ GType		camel_stream_get_type		(void);
 gssize		camel_stream_read		(CamelStream *stream,
 						 gchar *buffer,
 						 gsize n,
+						 GCancellable *cancellable,
 						 GError **error);
 gssize		camel_stream_write		(CamelStream *stream,
 						 const gchar *buffer,
 						 gsize n,
+						 GCancellable *cancellable,
 						 GError **error);
 gint		camel_stream_flush		(CamelStream *stream,
+						 GCancellable *cancellable,
 						 GError **error);
 gint		camel_stream_close		(CamelStream *stream,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_stream_eos		(CamelStream *stream);
 gint		camel_stream_reset		(CamelStream *stream,
@@ -103,6 +111,7 @@ gint		camel_stream_reset		(CamelStream *stream,
 /* utility macros and funcs */
 gssize		camel_stream_write_string	(CamelStream *stream,
 						 const gchar *string,
+						 GCancellable *cancellable,
 						 GError **error);
 gssize		camel_stream_printf		(CamelStream *stream,
 						 const gchar *fmt,
@@ -115,6 +124,7 @@ gssize		camel_stream_vprintf		(CamelStream *stream,
  * either stream.  */
 gssize		camel_stream_write_to_stream	(CamelStream *stream,
 						 CamelStream *output_stream,
+						 GCancellable *cancellable,
 						 GError **error);
 
 G_END_DECLS
diff --git a/camel/camel-tcp-stream-raw.c b/camel/camel-tcp-stream-raw.c
index ac5fe96..74de8b9 100644
--- a/camel/camel-tcp-stream-raw.c
+++ b/camel/camel-tcp-stream-raw.c
@@ -261,18 +261,25 @@ _set_g_error_from_errno (GError **error, gboolean eintr_means_cancelled)
 }
 
 static gssize
-read_from_prfd (PRFileDesc *fd, gchar *buffer, gsize n, GError **error)
+read_from_prfd (PRFileDesc *fd,
+                gchar *buffer,
+                gsize n,
+                GCancellable *cancellable,
+                GError **error)
 {
-	PRFileDesc *cancel_fd;
+	PRFileDesc *cancel_fd = NULL;
 	gssize nread;
 
-	if (camel_operation_cancel_check (NULL)) {
+	if (g_cancellable_is_cancelled (cancellable)) {
 		errno = EINTR;
 		_set_g_error_from_errno (error, TRUE);
 		return -1;
 	}
 
-	cancel_fd = camel_operation_cancel_prfd (NULL);
+	if (CAMEL_IS_OPERATION (cancellable))
+		cancel_fd = camel_operation_cancel_prfd (
+			CAMEL_OPERATION (cancellable));
+
 	if (cancel_fd == NULL) {
 		do {
 			nread = PR_Read (fd, buffer, n);
@@ -350,27 +357,35 @@ static gssize
 tcp_stream_raw_read (CamelStream *stream,
                      gchar *buffer,
                      gsize n,
+                     GCancellable *cancellable,
                      GError **error)
 {
 	CamelTcpStreamRaw *raw = CAMEL_TCP_STREAM_RAW (stream);
 	CamelTcpStreamRawPrivate *priv = raw->priv;
 
-	return read_from_prfd (priv->sockfd, buffer, n, error);
+	return read_from_prfd (priv->sockfd, buffer, n, cancellable, error);
 }
 
 static gssize
-write_to_prfd (PRFileDesc *fd, const gchar *buffer, gsize n, GError **error)
+write_to_prfd (PRFileDesc *fd,
+               const gchar *buffer,
+               gsize n,
+               GCancellable *cancellable,
+               GError **error)
 {
+	PRFileDesc *cancel_fd = NULL;
 	gssize w, written = 0;
-	PRFileDesc *cancel_fd;
 
-	if (camel_operation_cancel_check (NULL)) {
+	if (g_cancellable_is_cancelled (cancellable)) {
 		errno = EINTR;
 		_set_g_error_from_errno (error, TRUE);
 		return -1;
 	}
 
-	cancel_fd = camel_operation_cancel_prfd (NULL);
+	if (CAMEL_IS_OPERATION (cancellable))
+		cancel_fd = camel_operation_cancel_prfd (
+			CAMEL_OPERATION (cancellable));
+
 	if (cancel_fd == NULL) {
 		do {
 			do {
@@ -457,16 +472,18 @@ static gssize
 tcp_stream_raw_write (CamelStream *stream,
                       const gchar *buffer,
                       gsize n,
+                      GCancellable *cancellable,
                       GError **error)
 {
 	CamelTcpStreamRaw *raw = CAMEL_TCP_STREAM_RAW (stream);
 	CamelTcpStreamRawPrivate *priv = raw->priv;
 
-	return write_to_prfd (priv->sockfd, buffer, n, error);
+	return write_to_prfd (priv->sockfd, buffer, n, cancellable, error);
 }
 
 static gint
 tcp_stream_raw_flush (CamelStream *stream,
+                      GCancellable *cancellable,
                       GError **error)
 {
 #if 0
@@ -480,6 +497,7 @@ tcp_stream_raw_flush (CamelStream *stream,
 
 static gint
 tcp_stream_raw_close (CamelStream *stream,
+                      GCancellable *cancellable,
                       GError **error)
 {
 	CamelTcpStreamRaw *raw = CAMEL_TCP_STREAM_RAW (stream);
@@ -546,10 +564,12 @@ sockaddr_to_praddr (struct sockaddr *s, gint len, PRNetAddr *addr)
 }
 
 static PRFileDesc *
-socket_connect (struct addrinfo *host, GError **error)
+socket_connect (struct addrinfo *host,
+                GCancellable *cancellable,
+                GError **error)
 {
 	PRNetAddr netaddr;
-	PRFileDesc *fd, *cancel_fd;
+	PRFileDesc *fd, *cancel_fd = NULL;
 
 	if (sockaddr_to_praddr (host->ai_addr, host->ai_addrlen, &netaddr) != 0) {
 		errno = EINVAL;
@@ -564,7 +584,9 @@ socket_connect (struct addrinfo *host, GError **error)
 		return NULL;
 	}
 
-	cancel_fd = camel_operation_cancel_prfd (NULL);
+	if (CAMEL_IS_OPERATION (cancellable))
+		cancel_fd = camel_operation_cancel_prfd (
+			CAMEL_OPERATION (cancellable));
 
 	if (PR_Connect (fd, &netaddr, cancel_fd?0:CONNECT_TIMEOUT) == PR_FAILURE) {
 		gint errnosave;
@@ -629,7 +651,11 @@ out:
  * negotiate anything with the proxy; this is just to create the socket and connect.
  */
 static PRFileDesc *
-connect_to_proxy (CamelTcpStreamRaw *raw, const gchar *proxy_host, gint proxy_port, GError **error)
+connect_to_proxy (CamelTcpStreamRaw *raw,
+                  const gchar *proxy_host,
+                  gint proxy_port,
+                  GCancellable *cancellable,
+                  GError **error)
 {
 	struct addrinfo *addr, *ai, hints;
 	gchar serv[16];
@@ -645,7 +671,8 @@ connect_to_proxy (CamelTcpStreamRaw *raw, const gchar *proxy_host, gint proxy_po
 	memset (&hints, 0, sizeof (hints));
 	hints.ai_socktype = SOCK_STREAM;
 
-	addr = camel_getaddrinfo (proxy_host, serv, &hints, error);
+	addr = camel_getaddrinfo (
+		proxy_host, serv, &hints, cancellable, error);
 	if (!addr)
 		return NULL;
 
@@ -653,7 +680,7 @@ connect_to_proxy (CamelTcpStreamRaw *raw, const gchar *proxy_host, gint proxy_po
 
 	ai = addr;
 	while (ai) {
-		fd = socket_connect (ai, error);
+		fd = socket_connect (ai, cancellable, error);
 		if (fd)
 			goto out;
 
@@ -679,7 +706,12 @@ out:
  * connect_addr; if you want to traverse all the addrinfos, call this function for each of them.
  */
 static PRFileDesc *
-connect_to_socks4_proxy (CamelTcpStreamRaw *raw, const gchar *proxy_host, gint proxy_port, struct addrinfo *connect_addr, GError **error)
+connect_to_socks4_proxy (CamelTcpStreamRaw *raw,
+                         const gchar *proxy_host,
+                         gint proxy_port,
+                         struct addrinfo *connect_addr,
+                         GCancellable *cancellable,
+                         GError **error)
 {
 	PRFileDesc *fd;
 	gchar request[9];
@@ -689,7 +721,8 @@ connect_to_socks4_proxy (CamelTcpStreamRaw *raw, const gchar *proxy_host, gint p
 
 	g_assert (connect_addr->ai_addr->sa_family == AF_INET);
 
-	fd = connect_to_proxy (raw, proxy_host, proxy_port, error);
+	fd = connect_to_proxy (
+		raw, proxy_host, proxy_port, cancellable, error);
 	if (!fd)
 		goto error;
 
@@ -702,13 +735,13 @@ connect_to_socks4_proxy (CamelTcpStreamRaw *raw, const gchar *proxy_host, gint p
 	request[8] = 0x00;				/* terminator */
 
 	d (g_print ("  writing SOCKS4 request to connect to actual host\n"));
-	if (write_to_prfd (fd, request, sizeof (request), error) != sizeof (request)) {
+	if (write_to_prfd (fd, request, sizeof (request), cancellable, error) != sizeof (request)) {
 		d (g_print ("  failed: %d\n", errno));
 		goto error;
 	}
 
 	d (g_print ("  reading SOCKS4 reply\n"));
-	if (read_from_prfd (fd, reply, sizeof (reply), error) != sizeof (reply)) {
+	if (read_from_prfd (fd, reply, sizeof (reply), cancellable, error) != sizeof (reply)) {
 		d (g_print ("  failed: %d\n", errno));
 		g_set_error (error, CAMEL_PROXY_ERROR, CAMEL_PROXY_ERROR_PROXY_NOT_SUPPORTED,
 			     _("The proxy host does not support SOCKS4"));
@@ -762,7 +795,10 @@ out:
 
 /* Resolves a port number using getaddrinfo().  Returns 0 if the port can't be resolved or if the operation is cancelled */
 static gint
-resolve_port (const gchar *service, gint fallback_port, GError **error)
+resolve_port (const gchar *service,
+              gint fallback_port,
+              GCancellable *cancellable,
+              GError **error)
 {
 	struct addrinfo *ai;
 	GError *my_error;
@@ -775,7 +811,8 @@ resolve_port (const gchar *service, gint fallback_port, GError **error)
 	 * from the standard getaddrinfo(), which lets you pass a NULL hostname
 	 * if you just want to resolve a port number.
 	 */
-	ai = camel_getaddrinfo ("localhost", service, NULL, &my_error);
+	ai = camel_getaddrinfo (
+		"localhost", service, NULL, cancellable, &my_error);
 	if (ai == NULL && fallback_port != 0 && !g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
 		port = fallback_port;
 	else if (ai == NULL) {
@@ -802,7 +839,10 @@ resolve_port (const gchar *service, gint fallback_port, GError **error)
 }
 
 static gboolean
-socks5_initiate_and_request_authentication (CamelTcpStreamRaw *raw, PRFileDesc *fd, GError **error)
+socks5_initiate_and_request_authentication (CamelTcpStreamRaw *raw,
+                                            PRFileDesc *fd,
+                                            GCancellable *cancellable,
+                                            GError **error)
 {
 	gchar request[3];
 	gchar reply[2];
@@ -812,13 +852,13 @@ socks5_initiate_and_request_authentication (CamelTcpStreamRaw *raw, PRFileDesc *
 	request[2] = 0;		/* no authentication, please - extending this is left as an exercise for the reader */
 
 	d (g_print ("  writing SOCKS5 request for authentication\n"));
-	if (write_to_prfd (fd, request, sizeof (request), error) != sizeof (request)) {
+	if (write_to_prfd (fd, request, sizeof (request), cancellable, error) != sizeof (request)) {
 		d (g_print ("  failed: %d\n", errno));
 		return FALSE;
 	}
 
 	d (g_print ("  reading SOCKS5 reply\n"));
-	if (read_from_prfd (fd, reply, sizeof (reply), error) != sizeof (reply)) {
+	if (read_from_prfd (fd, reply, sizeof (reply), cancellable, error) != sizeof (reply)) {
 		d (g_print ("  failed: %d\n", errno));
 		g_clear_error (error);
 		g_set_error (error, CAMEL_PROXY_ERROR, CAMEL_PROXY_ERROR_PROXY_NOT_SUPPORTED,
@@ -859,7 +899,10 @@ socks5_reply_error_to_string (gchar error_code)
 }
 
 static gboolean
-socks5_consume_reply_address (CamelTcpStreamRaw *raw, PRFileDesc *fd, GError **error)
+socks5_consume_reply_address (CamelTcpStreamRaw *raw,
+                              PRFileDesc *fd,
+                              GCancellable *cancellable,
+                              GError **error)
 {
 	gchar address_type;
 	gint bytes_to_consume;
@@ -867,7 +910,7 @@ socks5_consume_reply_address (CamelTcpStreamRaw *raw, PRFileDesc *fd, GError **e
 
 	address_and_port = NULL;
 
-	if (read_from_prfd (fd, &address_type, sizeof (address_type), error) != sizeof (address_type))
+	if (read_from_prfd (fd, &address_type, sizeof (address_type), cancellable, error) != sizeof (address_type))
 		goto incomplete_reply;
 
 	if (address_type == 0x01)
@@ -879,7 +922,7 @@ socks5_consume_reply_address (CamelTcpStreamRaw *raw, PRFileDesc *fd, GError **e
 
 		/* we'll get an octet with the address length, and then the address itself */
 
-		if (read_from_prfd (fd, (gchar *) &address_len, sizeof (address_len), error) != sizeof (address_len))
+		if (read_from_prfd (fd, (gchar *) &address_len, sizeof (address_len), cancellable, error) != sizeof (address_len))
 			goto incomplete_reply;
 
 		bytes_to_consume = address_len;
@@ -891,7 +934,7 @@ socks5_consume_reply_address (CamelTcpStreamRaw *raw, PRFileDesc *fd, GError **e
 	bytes_to_consume += 2; /* 2 octets for port number */
 	address_and_port = g_new (gchar, bytes_to_consume);
 
-	if (read_from_prfd (fd, address_and_port, bytes_to_consume, error) != bytes_to_consume)
+	if (read_from_prfd (fd, address_and_port, bytes_to_consume, cancellable, error) != bytes_to_consume)
 		goto incomplete_reply;
 
 	g_free (address_and_port); /* Currently we don't do anything to these; maybe some authenticated method will need them later */
@@ -907,7 +950,12 @@ incomplete_reply:
 }
 
 static gboolean
-socks5_request_connect (CamelTcpStreamRaw *raw, PRFileDesc *fd, const gchar *host, gint port, GError **error)
+socks5_request_connect (CamelTcpStreamRaw *raw,
+                        PRFileDesc *fd,
+                        const gchar *host,
+                        gint port,
+                        GCancellable *cancellable,
+                        GError **error)
 {
 	gchar *request;
 	gchar reply[3];
@@ -934,7 +982,7 @@ socks5_request_connect (CamelTcpStreamRaw *raw, PRFileDesc *fd, const gchar *hos
 	request[5 + host_len + 1] = port & 0xff;      /* low byte of port */
 
 	d (g_print ("  writing SOCKS5 request for connection\n"));
-	num_written = write_to_prfd (fd, request, request_len, error);
+	num_written = write_to_prfd (fd, request, request_len, cancellable, error);
 	g_free (request);
 
 	if (num_written != request_len) {
@@ -943,7 +991,7 @@ socks5_request_connect (CamelTcpStreamRaw *raw, PRFileDesc *fd, const gchar *hos
 	}
 
 	d (g_print ("  reading SOCKS5 reply\n"));
-	if (read_from_prfd (fd, reply, sizeof (reply), error) != sizeof (reply)) {
+	if (read_from_prfd (fd, reply, sizeof (reply), cancellable, error) != sizeof (reply)) {
 		d (g_print ("  failed: %d\n", errno));
 		return FALSE;
 	}
@@ -967,7 +1015,7 @@ socks5_request_connect (CamelTcpStreamRaw *raw, PRFileDesc *fd, const gchar *hos
 	 * identify to the final host.  This is of variable length, so we must
 	 * consume it by hand.
 	 */
-	if (!socks5_consume_reply_address (raw, fd, error))
+	if (!socks5_consume_reply_address (raw, fd, cancellable, error))
 		return FALSE;
 
 	return TRUE;
@@ -976,25 +1024,30 @@ socks5_request_connect (CamelTcpStreamRaw *raw, PRFileDesc *fd, const gchar *hos
 /* RFC 1928 - SOCKS protocol version 5 */
 static PRFileDesc *
 connect_to_socks5_proxy (CamelTcpStreamRaw *raw,
-			 const gchar *proxy_host, gint proxy_port,
-			 const gchar *host, const gchar *service, gint fallback_port,
-			 GError **error)
+                         const gchar *proxy_host,
+                         gint proxy_port,
+                         const gchar *host,
+                         const gchar *service,
+                         gint fallback_port,
+                         GCancellable *cancellable,
+                         GError **error)
 {
 	PRFileDesc *fd;
 	gint port;
 
-	fd = connect_to_proxy (raw, proxy_host, proxy_port, error);
+	fd = connect_to_proxy (
+		raw, proxy_host, proxy_port, cancellable, error);
 	if (!fd)
 		goto error;
 
-	port = resolve_port (service, fallback_port, error);
+	port = resolve_port (service, fallback_port, cancellable, error);
 	if (port == 0)
 		goto error;
 
-	if (!socks5_initiate_and_request_authentication (raw, fd, error))
+	if (!socks5_initiate_and_request_authentication (raw, fd, cancellable, error))
 		goto error;
 
-	if (!socks5_request_connect (raw, fd, host, port, error))
+	if (!socks5_request_connect (raw, fd, host, port, cancellable, error))
 		goto error;
 
 	d (g_print ("  success\n"));
@@ -1024,7 +1077,10 @@ out:
 
 static gint
 tcp_stream_raw_connect (CamelTcpStream *stream,
-			const gchar *host, const gchar *service, gint fallback_port,
+                        const gchar *host,
+                        const gchar *service,
+                        gint fallback_port,
+                        GCancellable *cancellable,
                         GError **error)
 {
 	CamelTcpStreamRaw *raw = CAMEL_TCP_STREAM_RAW (stream);
@@ -1042,7 +1098,9 @@ tcp_stream_raw_connect (CamelTcpStream *stream,
 		/* First, try SOCKS5, which does name resolution itself */
 
 		my_error = NULL;
-		priv->sockfd = connect_to_socks5_proxy (raw, proxy_host, proxy_port, host, service, fallback_port, &my_error);
+		priv->sockfd = connect_to_socks5_proxy (
+			raw, proxy_host, proxy_port, host, service,
+			fallback_port, cancellable, &my_error);
 		if (priv->sockfd)
 			return 0;
 		else if (g_error_matches (my_error, CAMEL_PROXY_ERROR, CAMEL_PROXY_ERROR_CANT_AUTHENTICATE)
@@ -1059,13 +1117,15 @@ tcp_stream_raw_connect (CamelTcpStream *stream,
 	hints.ai_family = PF_UNSPEC;
 
 	my_error = NULL;
-	addr = camel_getaddrinfo (host, service, &hints, &my_error);
+	addr = camel_getaddrinfo (
+		host, service, &hints, cancellable, &my_error);
 	if (addr == NULL && fallback_port != 0 && !g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
 		gchar str_port[16];
 
 		g_clear_error (&my_error);
 		sprintf (str_port, "%d", fallback_port);
-		addr = camel_getaddrinfo (host, str_port, &hints, &my_error);
+		addr = camel_getaddrinfo (
+			host, str_port, &hints, cancellable, &my_error);
 	}
 
 	if (addr == NULL) {
@@ -1079,9 +1139,11 @@ tcp_stream_raw_connect (CamelTcpStream *stream,
 		if (proxy_host) {
 			/* SOCKS4 only does IPv4 */
 			if (ai->ai_addr->sa_family == AF_INET)
-				priv->sockfd = connect_to_socks4_proxy (raw, proxy_host, proxy_port, ai, error);
+				priv->sockfd = connect_to_socks4_proxy (
+					raw, proxy_host, proxy_port,
+					ai, cancellable, error);
 		} else
-			priv->sockfd = socket_connect (ai, error);
+			priv->sockfd = socket_connect (ai, cancellable, error);
 
 		if (priv->sockfd) {
 			retval = 0;
diff --git a/camel/camel-tcp-stream-ssl.c b/camel/camel-tcp-stream-ssl.c
index 02c7db8..057630f 100644
--- a/camel/camel-tcp-stream-ssl.c
+++ b/camel/camel-tcp-stream-ssl.c
@@ -384,11 +384,11 @@ camel_certdb_nss_cert_set (CamelCertDB *certdb, CamelCert *ccert, CERTCertificat
 	if (stream != NULL) {
 		if (camel_stream_write (
 			stream, (const gchar *) ccert->rawcert->data,
-			ccert->rawcert->len, NULL) == -1) {
+			ccert->rawcert->len, NULL, NULL) == -1) {
 			g_warning ("Could not save cert: %s: %s", path, g_strerror (errno));
 			g_unlink (path);
 		}
-		camel_stream_close (stream, NULL);
+		camel_stream_close (stream, NULL, NULL);
 		g_object_unref (stream);
 	} else {
 		g_warning ("Could not save cert: %s: %s", path, g_strerror (errno));
@@ -706,12 +706,19 @@ rehandshake_ssl (PRFileDesc *fd, GError **error)
 }
 
 static gint
-tcp_stream_ssl_connect (CamelTcpStream *stream, const gchar *host, const gchar *service, gint fallback_port, GError **error)
+tcp_stream_ssl_connect (CamelTcpStream *stream,
+                        const gchar *host,
+                        const gchar *service,
+                        gint fallback_port,
+                        GCancellable *cancellable,
+                        GError **error)
 {
 	CamelTcpStreamSSL *ssl = CAMEL_TCP_STREAM_SSL (stream);
 	gint retval;
 
-	retval = CAMEL_TCP_STREAM_CLASS (camel_tcp_stream_ssl_parent_class)->connect (stream, host, service, fallback_port, error);
+	retval = CAMEL_TCP_STREAM_CLASS (camel_tcp_stream_ssl_parent_class)->
+		connect (stream, host, service,
+		fallback_port, cancellable, error);
 	if (retval != 0)
 		return retval;
 
diff --git a/camel/camel-tcp-stream.c b/camel/camel-tcp-stream.c
index a9d3587..f7945e5 100644
--- a/camel/camel-tcp-stream.c
+++ b/camel/camel-tcp-stream.c
@@ -85,6 +85,7 @@ camel_tcp_stream_init (CamelTcpStream *tcp_stream)
  * @host: Hostname for connection
  * @service: Service name or port number in string form
  * @fallback_port: Port number to retry if @service is not present in the system's services database, or 0 to avoid retrying.
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Create a socket and connect based upon the data provided.
@@ -93,7 +94,10 @@ camel_tcp_stream_init (CamelTcpStream *tcp_stream)
  **/
 gint
 camel_tcp_stream_connect (CamelTcpStream *stream,
-			  const gchar *host, const gchar *service, gint fallback_port,
+			  const gchar *host,
+                          const gchar *service,
+                          gint fallback_port,
+                          GCancellable *cancellable,
                           GError **error)
 {
 	CamelTcpStreamClass *class;
@@ -107,7 +111,8 @@ camel_tcp_stream_connect (CamelTcpStream *stream,
 	class = CAMEL_TCP_STREAM_GET_CLASS (stream);
 	g_return_val_if_fail (class->connect != NULL, -1);
 
-	retval = class->connect (stream, host, service, fallback_port, error);
+	retval = class->connect (
+		stream, host, service, fallback_port, cancellable, error);
 	CAMEL_CHECK_GERROR (stream, connect, retval == 0, error);
 
 	return retval;
diff --git a/camel/camel-tcp-stream.h b/camel/camel-tcp-stream.h
index 217dc88..0340cf1 100644
--- a/camel/camel-tcp-stream.h
+++ b/camel/camel-tcp-stream.h
@@ -125,7 +125,10 @@ struct _CamelTcpStreamClass {
 	CamelStreamClass parent_class;
 
 	gint		(*connect)		(CamelTcpStream *stream,
-						 const gchar *host, const gchar *service, gint fallback_port,
+						 const gchar *host,
+						 const gchar *service,
+						 gint fallback_port,
+						 GCancellable *cancellable,
 						 GError **error);
 	gint		(*getsockopt)		(CamelTcpStream *stream,
 						 CamelSockOptData *data);
@@ -143,7 +146,10 @@ struct _CamelTcpStreamClass {
 
 GType		camel_tcp_stream_get_type	(void);
 gint		camel_tcp_stream_connect	(CamelTcpStream *stream,
-						 const gchar *host, const gchar *service, gint fallback_port,
+						 const gchar *host,
+						 const gchar *service,
+						 gint fallback_port,
+						 GCancellable *cancellable,
 						 GError **error);
 gint		camel_tcp_stream_getsockopt	(CamelTcpStream *stream,
 						 CamelSockOptData *data);
diff --git a/camel/camel-transport.c b/camel/camel-transport.c
index 7f07045..1f9af07 100644
--- a/camel/camel-transport.c
+++ b/camel/camel-transport.c
@@ -80,6 +80,7 @@ camel_transport_init (CamelTransport *transport)
  * @message: a #CamelMimeMessage to send
  * @from: a #CamelAddress to send from
  * @recipients: a #CamelAddress containing all recipients
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * Sends the message to the given recipients, regardless of the contents
@@ -93,6 +94,7 @@ camel_transport_send_to (CamelTransport *transport,
                          CamelMimeMessage *message,
                          CamelAddress *from,
                          CamelAddress *recipients,
+                         GCancellable *cancellable,
                          GError **error)
 {
 	CamelTransportClass *class;
@@ -108,7 +110,8 @@ camel_transport_send_to (CamelTransport *transport,
 
 	camel_transport_lock (transport, CAMEL_TRANSPORT_SEND_LOCK);
 
-	success = class->send_to (transport, message, from, recipients, error);
+	success = class->send_to (
+		transport, message, from, recipients, cancellable, error);
 	CAMEL_CHECK_GERROR (transport, send_to, success, error);
 
 	camel_transport_unlock (transport, CAMEL_TRANSPORT_SEND_LOCK);
diff --git a/camel/camel-transport.h b/camel/camel-transport.h
index 92d88da..3456591 100644
--- a/camel/camel-transport.h
+++ b/camel/camel-transport.h
@@ -80,6 +80,7 @@ struct _CamelTransportClass {
 						 CamelMimeMessage *message,
 						 CamelAddress *from,
 						 CamelAddress *recipients,
+						 GCancellable *cancellable,
 						 GError **error);
 };
 
@@ -88,6 +89,7 @@ gboolean	camel_transport_send_to		(CamelTransport *transport,
 						 CamelMimeMessage *message,
 						 CamelAddress *from,
 						 CamelAddress *recipients,
+						 GCancellable *cancellable,
 						 GError **error);
 void		camel_transport_lock		(CamelTransport *transport,
 						 CamelTransportLock lock);
diff --git a/camel/camel-uid-cache.c b/camel/camel-uid-cache.c
index 17ea6c9..5a79c37 100644
--- a/camel/camel-uid-cache.c
+++ b/camel/camel-uid-cache.c
@@ -79,7 +79,7 @@ camel_uid_cache_new (const gchar *filename)
 
 	buf = g_malloc (st.st_size + 1);
 
-	if (st.st_size > 0 && camel_read (fd, buf, st.st_size, NULL) == -1) {
+	if (st.st_size > 0 && camel_read (fd, buf, st.st_size, NULL, NULL) == -1) {
 		close (fd);
 		g_free (buf);
 		return NULL;
@@ -124,8 +124,8 @@ maybe_write_uid (gpointer key, gpointer value, gpointer data)
 		return;
 
 	if (state && state->level == cache->level && state->save) {
-		if (camel_write (cache->fd, key, strlen (key), NULL) == -1 ||
-		    camel_write (cache->fd, "\n", 1, NULL) == -1) {
+		if (camel_write (cache->fd, key, strlen (key), NULL, NULL) == -1 ||
+		    camel_write (cache->fd, "\n", 1, NULL, NULL) == -1) {
 			cache->fd = -1;
 		} else {
 			cache->size += strlen (key) + 1;
diff --git a/camel/camel-vee-folder.c b/camel/camel-vee-folder.c
index e89318a..233ea1a 100644
--- a/camel/camel-vee-folder.c
+++ b/camel/camel-vee-folder.c
@@ -840,7 +840,9 @@ folder_renamed (CamelFolder *sub,
 }
 
 static void
-vee_folder_stop_folder (CamelVeeFolder *vf, CamelFolder *sub)
+vee_folder_stop_folder (CamelVeeFolder *vf,
+                        CamelFolder *sub,
+                        GCancellable *cancellable)
 {
 	CamelVeeFolderPrivate *p = CAMEL_VEE_FOLDER_GET_PRIVATE (vf);
 	gint i;
@@ -949,7 +951,7 @@ vee_folder_dispose (GObject *object)
 			camel_folder_freeze ((CamelFolder *)vf);
 			while (vf->priv->folders) {
 				CamelFolder *f = vf->priv->folders->data;
-				vee_folder_stop_folder (vf, f);
+				vee_folder_stop_folder (vf, f, NULL);
 			}
 			camel_folder_thaw ((CamelFolder *)vf);
 		}
@@ -985,6 +987,7 @@ vee_folder_finalize (GObject *object)
 
 static gboolean
 vee_folder_refresh_info (CamelFolder *folder,
+                         GCancellable *cancellable,
                          GError **error)
 {
 	CamelVeeFolder *vf = (CamelVeeFolder *)folder;
@@ -1017,6 +1020,7 @@ vee_folder_refresh_info (CamelFolder *folder,
 static gboolean
 vee_folder_sync (CamelFolder *folder,
                  gboolean expunge,
+                 GCancellable *cancellable,
                  GError **error)
 {
 	CamelVeeFolder *vf = (CamelVeeFolder *)folder;
@@ -1034,7 +1038,7 @@ vee_folder_sync (CamelFolder *folder,
 	while (node) {
 		CamelFolder *f = node->data;
 
-		if (!camel_folder_sync (f, expunge, &local_error)) {
+		if (!camel_folder_sync (f, expunge, cancellable, &local_error)) {
 			if (strncmp (local_error->message, "no such table", 13) != 0) {
 				const gchar *desc;
 
@@ -1091,17 +1095,20 @@ vee_folder_sync (CamelFolder *folder,
 
 static gboolean
 vee_folder_expunge (CamelFolder *folder,
+                    GCancellable *cancellable,
                     GError **error)
 {
 	/* Force it to rebuild the counts, when some folders were expunged. */
 	((CamelVeeSummary *) folder->summary)->force_counts = TRUE;
 
-	return CAMEL_FOLDER_GET_CLASS (folder)->sync (folder, TRUE, error);
+	return CAMEL_FOLDER_GET_CLASS (folder)->
+		sync (folder, TRUE, cancellable, error);
 }
 
 static CamelMimeMessage *
 vee_folder_get_message (CamelFolder *folder,
                         const gchar *uid,
+                        GCancellable *cancellable,
                         GError **error)
 {
 	CamelVeeMessageInfo *mi;
@@ -1109,7 +1116,9 @@ vee_folder_get_message (CamelFolder *folder,
 
 	mi = (CamelVeeMessageInfo *)camel_folder_summary_uid (folder->summary, uid);
 	if (mi) {
-		msg = camel_folder_get_message (mi->summary->folder, camel_message_info_uid (mi)+8, error);
+		msg = camel_folder_get_message (
+			mi->summary->folder, camel_message_info_uid (mi)+8,
+			cancellable, error);
 		camel_message_info_free ((CamelMessageInfo *)mi);
 	} else {
 		g_set_error (
@@ -1127,10 +1136,11 @@ vee_folder_append_message (CamelFolder *folder,
                            CamelMimeMessage *message,
                            const CamelMessageInfo *info,
                            gchar **appended_uid,
+                           GCancellable *cancellable,
                            GError **error)
 {
 	g_set_error (
-		error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
+		error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
 		_("Cannot copy or move messages into a Virtual Folder"));
 
 	return FALSE;
@@ -1142,10 +1152,11 @@ vee_folder_transfer_messages_to (CamelFolder *folder,
                                  CamelFolder *dest,
                                  GPtrArray **transferred_uids,
                                  gboolean delete_originals,
+                                 GCancellable *cancellable,
                                  GError **error)
 {
 	g_set_error (
-		error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
+		error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
 		_("Cannot copy or move messages into a Virtual Folder"));
 
 	return FALSE;
@@ -2102,7 +2113,8 @@ camel_vee_folder_add_folder (CamelVeeFolder *vf, CamelFolder *sub)
  * Removed the source folder, @sub, from the virtual folder, @vf.
  **/
 void
-camel_vee_folder_remove_folder (CamelVeeFolder *vf, CamelFolder *sub)
+camel_vee_folder_remove_folder (CamelVeeFolder *vf,
+                                CamelFolder *sub)
 {
 	CamelVeeFolderPrivate *p = CAMEL_VEE_FOLDER_GET_PRIVATE (vf);
 	gint i;
@@ -2189,7 +2201,9 @@ camel_vee_folder_rebuild_folder (CamelVeeFolder *vf,
 }
 
 static void
-remove_folders (CamelFolder *folder, CamelFolder *foldercopy, CamelVeeFolder *vf)
+remove_folders (CamelFolder *folder,
+                CamelFolder *foldercopy,
+                CamelVeeFolder *vf)
 {
 	camel_vee_folder_remove_folder (vf, folder);
 	g_object_unref (folder);
diff --git a/camel/camel-vee-folder.h b/camel/camel-vee-folder.h
index 3111c48..6909074 100644
--- a/camel/camel-vee-folder.h
+++ b/camel/camel-vee-folder.h
@@ -91,16 +91,25 @@ struct _CamelVeeFolderClass {
 
 	/* TODO: Some of this may need some additional work/thinking through, it works for now*/
 
-	void (*add_folder)(CamelVeeFolder *, CamelFolder *);
-	void (*remove_folder)(CamelVeeFolder *, CamelFolder *);
-	gint (*rebuild_folder)(CamelVeeFolder *, CamelFolder *, GError **error);
+	void		(*add_folder)		(CamelVeeFolder *vee_folder,
+						 CamelFolder *folder);
+	void		(*remove_folder)	(CamelVeeFolder *vee_folder,
+						 CamelFolder *folder);
+	gint		(*rebuild_folder)	(CamelVeeFolder *vee_folder,
+						 CamelFolder *folder,
+						 GError **error);
 
-	void (*set_expression)(CamelVeeFolder *, const gchar *);
+	void		(*set_expression)	(CamelVeeFolder *vee_folder,
+						 const gchar *expression);
 
 	/* Called for a folder-changed event on a source folder */
-	void (*folder_changed)(CamelVeeFolder *, CamelFolder *sub, CamelFolderChangeInfo *changes);
+	void		(*folder_changed)	(CamelVeeFolder *vee_folder,
+						 CamelFolder *subfolder,
+						 CamelFolderChangeInfo *changes);
 	/* Called for a folder-renamed event on a source folder */
-	void (*folder_renamed)(CamelVeeFolder *, CamelFolder *sub, const gchar *old);
+	void		(*folder_renamed)	(CamelVeeFolder *vee_folder,
+						 CamelFolder *subfolder,
+						 const gchar *old);
 };
 
 #define CAMEL_UNMATCHED_NAME "UNMATCHED"
@@ -112,7 +121,8 @@ void         camel_vee_folder_construct		(CamelVeeFolder *vf, guint32 flags);
 CamelFolder *camel_vee_folder_get_location (CamelVeeFolder *vf, const struct _CamelVeeMessageInfo *vinfo, gchar **realuid);
 
 void         camel_vee_folder_add_folder        (CamelVeeFolder *vf, CamelFolder *sub);
-void         camel_vee_folder_remove_folder     (CamelVeeFolder *vf, CamelFolder *sub);
+void		camel_vee_folder_remove_folder	(CamelVeeFolder *vf,
+						 CamelFolder *sub);
 void	     camel_vee_folder_set_folders	(CamelVeeFolder *vf, GList *folders);
 gint          camel_vee_folder_rebuild_folder (CamelVeeFolder *vf, CamelFolder *sub, GError **error);
 void	     camel_vee_folder_set_expression	(CamelVeeFolder *vf, const gchar *expr);
diff --git a/camel/camel-vee-store.c b/camel/camel-vee-store.c
index 027b679..6ccef77 100644
--- a/camel/camel-vee-store.c
+++ b/camel/camel-vee-store.c
@@ -157,6 +157,7 @@ static CamelFolder *
 vee_store_get_folder (CamelStore *store,
                       const gchar *folder_name,
                       guint32 flags,
+                      GCancellable *cancellable,
                       GError **error)
 {
 	CamelVeeFolder *vf;
@@ -199,6 +200,7 @@ static gboolean
 vee_store_rename_folder (CamelStore *store,
                          const gchar *old,
                          const gchar *new,
+                         GCancellable *cancellable,
                          GError **error)
 {
 	CamelFolder *folder, *oldfolder;
@@ -252,6 +254,7 @@ vee_store_rename_folder (CamelStore *store,
 static gboolean
 vee_store_delete_folder (CamelStore *store,
                          const gchar *folder_name,
+                         GCancellable *cancellable,
                          GError **error)
 {
 	CamelFolder *folder;
@@ -298,6 +301,7 @@ static CamelFolderInfo *
 vee_store_get_folder_info (CamelStore *store,
                            const gchar *top,
                            guint32 flags,
+                           GCancellable *cancellable,
                            GError **error)
 {
 	CamelFolderInfo *info, *res = NULL, *tail;
@@ -346,7 +350,9 @@ vee_store_get_folder_info (CamelStore *store,
 
 			/* ensures unread is correct */
 			if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0)
-				camel_folder_refresh_info ((CamelFolder *)folder, NULL);
+				camel_folder_refresh_info (
+					(CamelFolder *)folder,
+					cancellable, NULL);
 
 			parent_store = camel_folder_get_parent_store (CAMEL_FOLDER (folder));
 
@@ -433,6 +439,7 @@ vee_store_get_folder_info (CamelStore *store,
 
 static CamelFolder *
 vee_store_get_trash (CamelStore *store,
+                     GCancellable *cancellable,
                      GError **error)
 {
 	return NULL;
@@ -440,6 +447,7 @@ vee_store_get_trash (CamelStore *store,
 
 static CamelFolder *
 vee_store_get_junk (CamelStore *store,
+                    GCancellable *cancellable,
                     GError **error)
 {
 	return NULL;
diff --git a/camel/camel-vee-summary.c b/camel/camel-vee-summary.c
index 369ac88..b9b9593 100644
--- a/camel/camel-vee-summary.c
+++ b/camel/camel-vee-summary.c
@@ -230,7 +230,9 @@ camel_vee_summary_load_check_unread_vfolder (CamelVeeSummary *vs)
 }
 
 static gboolean
-vee_info_set_flags (CamelMessageInfo *mi, guint32 flags, guint32 set)
+vee_info_set_flags (CamelMessageInfo *mi,
+                    guint32 flags,
+                    guint32 set)
 {
 	gint res = FALSE;
 	CamelVeeFolder *vf = (CamelVeeFolder *)mi->summary->folder;
@@ -265,10 +267,10 @@ vee_info_set_flags (CamelMessageInfo *mi, guint32 flags, guint32 set)
 		if (hacked_unread_folder)
 			camel_vee_folder_mask_event_folder_changed ((CamelVeeFolder *)mi->summary->folder, rmi->summary->folder);
 
-		camel_folder_freeze (rmi->summary->folder);
-		res = camel_message_info_set_flags (rmi, flags, set);
+		camel_folder_freeze(rmi->summary->folder);
+		res = camel_message_info_set_flags(rmi, flags, set);
 		((CamelVeeMessageInfo *) mi)->old_flags = camel_message_info_flags (rmi);
-		camel_folder_thaw (rmi->summary->folder);
+		camel_folder_thaw(rmi->summary->folder);
 
 		if (hacked_unread_folder)
 			camel_vee_folder_unmask_event_folder_changed ((CamelVeeFolder *)mi->summary->folder, rmi->summary->folder);
diff --git a/camel/camel-vtrash-folder.c b/camel/camel-vtrash-folder.c
index f654501..b1f23c5 100644
--- a/camel/camel-vtrash-folder.c
+++ b/camel/camel-vtrash-folder.c
@@ -52,6 +52,7 @@ static struct {
 };
 
 struct _transfer_data {
+	GCancellable *cancellable;
 	CamelFolder *folder;
 	CamelFolder *dest;
 	GPtrArray *uids;
@@ -68,10 +69,15 @@ transfer_messages (CamelFolder *folder,
 	gint i;
 
 	camel_folder_transfer_messages_to (
-		md->folder, md->uids, md->dest, NULL, md->delete, error);
+		md->folder, md->uids, md->dest,
+		NULL, md->delete, md->cancellable, error);
+
+	if (md->cancellable != NULL)
+		g_object_unref (md->cancellable);
 
 	for (i=0;i<md->uids->len;i++)
 		g_free (md->uids->pdata[i]);
+
 	g_ptr_array_free (md->uids, TRUE);
 	g_object_unref (md->folder);
 	g_free (md);
@@ -82,6 +88,7 @@ vtrash_folder_append_message (CamelFolder *folder,
                               CamelMimeMessage *message,
                               const CamelMessageInfo *info,
                               gchar **appended_uid,
+                              GCancellable *cancellable,
                               GError **error)
 {
 	g_set_error (
@@ -97,6 +104,7 @@ vtrash_folder_transfer_messages_to (CamelFolder *source,
                                     CamelFolder *dest,
                                     GPtrArray **transferred_uids,
                                     gboolean delete_originals,
+                                    GCancellable *cancellable,
                                     GError **error)
 {
 	CamelVeeMessageInfo *mi;
@@ -125,7 +133,9 @@ vtrash_folder_transfer_messages_to (CamelFolder *source,
 
 		/* Move to trash is the same as setting the message flag */
 		for (i = 0; i < uids->len; i++)
-			camel_folder_set_message_flags (source, uids->pdata[i], ((CamelVTrashFolder *)dest)->bit, ~0);
+			camel_folder_set_message_flags (
+				source, uids->pdata[i],
+				((CamelVTrashFolder *)dest)->bit, ~0);
 		return TRUE;
 	}
 
@@ -144,17 +154,21 @@ vtrash_folder_transfer_messages_to (CamelFolder *source,
 
 		if (dest == mi->summary->folder) {
 			/* Just unset the flag on the original message */
-			camel_folder_set_message_flags (source, uids->pdata[i], sbit, 0);
+			camel_folder_set_message_flags (
+				source, uids->pdata[i], sbit, 0);
 		} else {
 			if (batch == NULL)
 				batch = g_hash_table_new (NULL, NULL);
 			md = g_hash_table_lookup (batch, mi->summary->folder);
 			if (md == NULL) {
-				md = g_malloc0 (sizeof (*md));
+				md = g_malloc0(sizeof(*md));
+				md->cancellable = cancellable;
 				md->folder = g_object_ref (mi->summary->folder);
 				md->uids = g_ptr_array_new ();
 				md->dest = dest;
-				g_hash_table_insert (batch, mi->summary->folder, md);
+				if (cancellable != NULL)
+					g_object_ref (cancellable);
+				g_hash_table_insert(batch, mi->summary->folder, md);
 			}
 
 			tuid = uids->pdata[i];
diff --git a/camel/providers/groupwise/camel-groupwise-folder.c b/camel/providers/groupwise/camel-groupwise-folder.c
index 1bd761c..15e278f 100644
--- a/camel/providers/groupwise/camel-groupwise-folder.c
+++ b/camel/providers/groupwise/camel-groupwise-folder.c
@@ -77,20 +77,20 @@ struct _CamelGroupwiseFolderPrivate {
 extern gint camel_application_is_exiting;
 
 /*prototypes*/
-static gboolean groupwise_transfer_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *destination, GPtrArray **transferred_uids, gboolean delete_originals, GError **error);
+static gboolean groupwise_transfer_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *destination, GPtrArray **transferred_uids, gboolean delete_originals, GCancellable *cancellable, GError **error);
 void convert_to_calendar (EGwItem *item, gchar **str, gint *len);
 static void convert_to_task (EGwItem *item, gchar **str, gint *len);
 static void convert_to_note (EGwItem *item, gchar **str, gint *len);
-static void gw_update_all_items ( CamelFolder *folder, GList *item_list, GError **error);
+static void gw_update_all_items ( CamelFolder *folder, GList *item_list, GCancellable *cancellable, GError **error);
 static void groupwise_populate_details_from_item (CamelMimeMessage *msg, EGwItem *item);
 static void groupwise_populate_msg_body_from_item (EGwConnection *cnc, CamelMultipart *multipart, EGwItem *item, gchar *body);
 static void groupwise_msg_set_recipient_list (CamelMimeMessage *msg, EGwItem *item);
-static void gw_update_cache ( CamelFolder *folder, GList *item_list, GError **error, gboolean uid_flag);
+static void gw_update_cache ( CamelFolder *folder, GList *item_list, gboolean uid_flag, GCancellable *cancellable, GError **error);
 static CamelMimeMessage *groupwise_folder_item_to_msg ( CamelFolder *folder, EGwItem *item, GError **error );
 static gchar * groupwise_get_filename (CamelFolder *folder, const gchar *uid, GError **error);
 static const gchar *get_from_from_org (EGwItemOrganizer *org);
-static void groupwise_refresh_folder (CamelFolder *folder, GError **error);
-static gboolean groupwise_sync (CamelFolder *folder, gboolean expunge, CamelMessageInfo *update_single, GError **error);
+static void groupwise_refresh_folder (CamelFolder *folder, GCancellable *cancellable, GError **error);
+static gboolean groupwise_sync (CamelFolder *folder, gboolean expunge, CamelMessageInfo *update_single, GCancellable *cancellable, GError **error);
 
 #define d(x)
 
@@ -109,7 +109,10 @@ groupwise_get_filename (CamelFolder *folder, const gchar *uid, GError **error)
 
 /* Get a message from cache if available otherwise get it from server */
 static CamelMimeMessage *
-groupwise_folder_get_message ( CamelFolder *folder, const gchar *uid, GError **error )
+groupwise_folder_get_message (CamelFolder *folder,
+                              const gchar *uid,
+                              GCancellable *cancellable,
+                              GError **error)
 {
 	CamelMimeMessage *msg = NULL;
 	CamelGroupwiseFolder *gw_folder;
@@ -144,9 +147,9 @@ groupwise_folder_get_message ( CamelFolder *folder, const gchar *uid, GError **e
 	if (cache_stream) {
 		msg = camel_mime_message_new ();
 		camel_stream_reset (stream, NULL);
-		camel_stream_write_to_stream (cache_stream, stream, NULL);
+		camel_stream_write_to_stream (cache_stream, stream, cancellable, NULL);
 		camel_stream_reset (stream, NULL);
-		if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) msg, stream, error) == -1) {
+		if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) msg, stream, cancellable, error) == -1) {
 			if (errno == EINTR) {
 				g_object_unref (msg);
 				g_object_unref (cache_stream);
@@ -179,7 +182,7 @@ groupwise_folder_get_message ( CamelFolder *folder, const gchar *uid, GError **e
 	}
 
 	/* Check if we are really offline */
-	if (!camel_groupwise_store_connected (gw_store, NULL)) {
+	if (!camel_groupwise_store_connected (gw_store, cancellable, NULL)) {
 		g_set_error (
 			error, CAMEL_SERVICE_ERROR,
 			CAMEL_SERVICE_ERROR_UNAVAILABLE,
@@ -226,8 +229,8 @@ groupwise_folder_get_message ( CamelFolder *folder, const gchar *uid, GError **e
 	/* add to cache */
 	CAMEL_GROUPWISE_FOLDER_REC_LOCK (folder, cache_lock);
 	if ((cache_stream = camel_data_cache_add (gw_folder->cache, "cache", uid, NULL))) {
-		if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *) msg, cache_stream, NULL) == -1
-				|| camel_stream_flush (cache_stream, NULL) == -1)
+		if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *) msg, cache_stream, cancellable, NULL) == -1
+				|| camel_stream_flush (cache_stream, cancellable, NULL) == -1)
 			camel_data_cache_remove (gw_folder->cache, "cache", uid, NULL);
 		g_object_unref (cache_stream);
 	}
@@ -658,7 +661,10 @@ error:
 }
 
 static void
-move_to_mailbox (CamelFolder *folder, CamelMessageInfo *info, GError **error)
+move_to_mailbox (CamelFolder *folder,
+                 CamelMessageInfo *info,
+                 GCancellable *cancellable,
+                 GError **error)
 {
 	CamelFolder *dest;
 	CamelStore *parent_store;
@@ -670,10 +676,13 @@ move_to_mailbox (CamelFolder *folder, CamelMessageInfo *info, GError **error)
 	uids = g_ptr_array_new ();
 	g_ptr_array_add (uids, (gpointer) uid);
 
-	dest = camel_store_get_folder (parent_store, "Mailbox", 0, error);
-	camel_message_info_set_flags (info, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_JUNK_LEARN|CAMEL_GW_MESSAGE_NOJUNK|CAMEL_GW_MESSAGE_JUNK, 0);
+	dest = camel_store_get_folder (parent_store, "Mailbox", 0, cancellable, error);
+	camel_message_info_set_flags (
+		info, CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_JUNK |
+		CAMEL_MESSAGE_JUNK_LEARN | CAMEL_GW_MESSAGE_NOJUNK |
+		CAMEL_GW_MESSAGE_JUNK, 0);
 	if (dest)
-		groupwise_transfer_messages_to (folder, uids, dest, NULL, TRUE, error);
+		groupwise_transfer_messages_to (folder, uids, dest, NULL, TRUE, cancellable, error);
 	else
 		g_warning ("No Mailbox folder found");
 
@@ -681,7 +690,10 @@ move_to_mailbox (CamelFolder *folder, CamelMessageInfo *info, GError **error)
 }
 
 static void
-move_to_junk (CamelFolder *folder, CamelMessageInfo *info, GError **error)
+move_to_junk (CamelFolder *folder,
+              CamelMessageInfo *info,
+              GCancellable *cancellable,
+              GError **error)
 {
 	CamelFolder *dest;
 	CamelFolderInfo *fi;
@@ -694,17 +706,17 @@ move_to_junk (CamelFolder *folder, CamelMessageInfo *info, GError **error)
 	uids = g_ptr_array_new ();
 	g_ptr_array_add (uids, (gpointer) uid);
 
-	dest = camel_store_get_folder (parent_store, JUNK_FOLDER, 0, error);
+	dest = camel_store_get_folder (parent_store, JUNK_FOLDER, 0, cancellable, error);
 
 	if (dest)
-		groupwise_transfer_messages_to (folder, uids, dest, NULL, TRUE, error);
+		groupwise_transfer_messages_to (folder, uids, dest, NULL, TRUE, cancellable, error);
 	else {
 		fi = create_junk_folder (parent_store);
-		dest = camel_store_get_folder (parent_store, JUNK_FOLDER, 0, error);
+		dest = camel_store_get_folder (parent_store, JUNK_FOLDER, 0, cancellable, error);
 		if (!dest)
 			g_warning ("Could not get JunkFolder:Message not moved");
 		else
-			groupwise_transfer_messages_to (folder, uids, dest, NULL, TRUE, error);
+			groupwise_transfer_messages_to (folder, uids, dest, NULL, TRUE, cancellable, error);
 	}
 	update_junk_list (parent_store, info, ADD_JUNK_ENTRY);
 }
@@ -765,7 +777,10 @@ sync_flags (CamelFolder *folder, GList *uids)
 }
 
 static gboolean
-groupwise_set_message_flags (CamelFolder *folder, const gchar *uid, guint32 flags, guint32 set)
+groupwise_set_message_flags (CamelFolder *folder,
+                             const gchar *uid,
+                             guint32 flags,
+                             guint32 set)
 {
 	CamelMessageInfo *info;
 	gint res;
@@ -781,22 +796,31 @@ groupwise_set_message_flags (CamelFolder *folder, const gchar *uid, guint32 flag
 
 	sync_immediately = g_getenv ("GW_SYNC_IMMEDIATE");
 
+	/* FIXME groupwise_sync() blocks, but this method is
+	 *       not supposed to block.  Potential hang here. */
 	if (sync_immediately)
-		groupwise_sync (folder, FALSE, info, NULL);
+		groupwise_sync (folder, FALSE, info, NULL, NULL);
 
 	camel_message_info_free (info);
 	return res;
 }
 
 static gboolean
-groupwise_sync_all (CamelFolder *folder, gboolean expunge, GError **error)
+groupwise_sync_all (CamelFolder *folder,
+                    gboolean expunge,
+                    GCancellable *cancellable,
+                    GError **error)
 {
-	return groupwise_sync (folder, expunge, NULL, error);
+	return groupwise_sync (folder, expunge, NULL, cancellable, error);
 }
 
 /* This may need to be reorganized. */
 static gboolean
-groupwise_sync (CamelFolder *folder, gboolean expunge, CamelMessageInfo *update_single, GError **error)
+groupwise_sync (CamelFolder *folder,
+                gboolean expunge,
+                CamelMessageInfo *update_single,
+                GCancellable *cancellable,
+                GError **error)
 {
 	CamelGroupwiseStore *gw_store;
 	CamelGroupwiseFolder *gw_folder;
@@ -826,7 +850,7 @@ groupwise_sync (CamelFolder *folder, gboolean expunge, CamelMessageInfo *update_
 		return groupwise_sync_summary (folder, error);
 
 	camel_service_lock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-	if (!camel_groupwise_store_connected (gw_store, NULL)) {
+	if (!camel_groupwise_store_connected (gw_store, cancellable, NULL)) {
 		camel_service_unlock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 		return TRUE;
 	}
@@ -866,7 +890,7 @@ groupwise_sync (CamelFolder *folder, gboolean expunge, CamelMessageInfo *update_
 
 		if ((flags & CAMEL_MESSAGE_JUNK) && strcmp (camel_folder_get_name (folder), JUNK_FOLDER)) {
 			/*marked a message junk*/
-			move_to_junk (folder, info, error);
+			move_to_junk (folder, info, cancellable, error);
 			camel_folder_summary_remove_uid (folder->summary, camel_message_info_uid (info));
 			camel_data_cache_remove (gw_folder->cache, "cache", camel_message_info_uid(info), NULL);
 			continue;
@@ -874,7 +898,7 @@ groupwise_sync (CamelFolder *folder, gboolean expunge, CamelMessageInfo *update_
 
 		if ((flags & CAMEL_GW_MESSAGE_NOJUNK) && !strcmp (camel_folder_get_name (folder), JUNK_FOLDER)) {
 			/*message was marked as junk, now unjunk*/
-			move_to_mailbox (folder, info, error);
+			move_to_mailbox (folder, info, cancellable, error);
 			camel_folder_summary_remove_uid (folder->summary, camel_message_info_uid (info));
 			camel_data_cache_remove (gw_folder->cache, "cache", camel_message_info_uid(info), NULL);
 			continue;
@@ -1040,7 +1064,11 @@ groupwise_sync (CamelFolder *folder, gboolean expunge, CamelMessageInfo *update_
 }
 
 CamelFolder *
-camel_gw_folder_new (CamelStore *store, const gchar *folder_name, const gchar *folder_dir, GError **error)
+camel_gw_folder_new (CamelStore *store,
+                     const gchar *folder_name,
+                     const gchar *folder_dir,
+                     GCancellable *cancellable,
+                     GError **error)
 {
 	CamelFolder *folder;
 	CamelGroupwiseFolder *gw_folder;
@@ -1116,7 +1144,8 @@ struct _folder_update_msg {
 };
 
 static void
-update_update (CamelSession *session, CamelSessionThreadMsg *msg)
+update_update (CamelSession *session,
+               CamelSessionThreadMsg *msg)
 {
 	struct _folder_update_msg *m = (struct _folder_update_msg *)msg;
 	EGwConnectionStatus status;
@@ -1141,7 +1170,8 @@ update_update (CamelSession *session, CamelSessionThreadMsg *msg)
 	}
 
 	camel_operation_start (
-		NULL, _("Checking for deleted messages %s"),
+		msg->cancellable,
+		_("Checking for deleted messages %s"),
 		camel_folder_get_name (m->folder));
 
 	status = e_gw_connection_create_cursor (m->cnc, m->container_id, "id", NULL, &cursor);
@@ -1211,13 +1241,13 @@ update_update (CamelSession *session, CamelSessionThreadMsg *msg)
 	  }*/
 
 	g_print ("\nNumber of items in the folder: %d \n", g_list_length(items_full_list));
-	gw_update_all_items (m->folder, items_full_list, NULL);
-	camel_operation_end (NULL);
+	gw_update_all_items (m->folder, items_full_list, NULL, NULL);
+	camel_operation_end (msg->cancellable);
 
 	return;
  end1:
 	camel_service_unlock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-	camel_operation_end (NULL);
+	camel_operation_end (msg->cancellable);
 	if (items_full_list) {
 		g_list_foreach (items_full_list, (GFunc)g_free, NULL);
 		g_list_free (items_full_list);
@@ -1244,7 +1274,9 @@ static CamelSessionThreadOps update_ops = {
 };
 
 static gboolean
-groupwise_refresh_info (CamelFolder *folder, GError **error)
+groupwise_refresh_info (CamelFolder *folder,
+                        GCancellable *cancellable,
+                        GError **error)
 {
 	CamelGroupwiseSummary *summary = (CamelGroupwiseSummary *) folder->summary;
 	CamelStoreInfo *si;
@@ -1263,7 +1295,7 @@ groupwise_refresh_info (CamelFolder *folder, GError **error)
 	 * should not interfere with the process
 	 */
 	if (summary->time_string && (strlen (summary->time_string) > 0))  {
-		groupwise_refresh_folder (folder, error);
+		groupwise_refresh_folder (folder, cancellable, error);
 		si = camel_store_summary_path ((CamelStoreSummary *)((CamelGroupwiseStore *)parent_store)->summary, full_name);
 		if (si) {
 			guint32 unread, total;
@@ -1285,7 +1317,7 @@ groupwise_refresh_info (CamelFolder *folder, GError **error)
 		 * so do a get_folder again. And hope that it works
 		 */
 		g_print("Reloading folder...something wrong with the summary....\n");
-		gw_store_reload_folder (gw_store, folder, 0, error);
+		gw_store_reload_folder (gw_store, folder, 0, cancellable, error);
 	}
 
 	return TRUE;
@@ -1375,7 +1407,9 @@ update_summary_string (CamelFolder *folder, const gchar *time_string)
 }
 
 static void
-groupwise_refresh_folder (CamelFolder *folder, GError **error)
+groupwise_refresh_folder (CamelFolder *folder,
+                          GCancellable *cancellable,
+                          GError **error)
 {
 	CamelGroupwiseStore *gw_store;
 	CamelGroupwiseFolder *gw_folder;
@@ -1409,7 +1443,7 @@ groupwise_refresh_folder (CamelFolder *folder, GError **error)
 
 	/* Sync-up the (un)read changes before getting updates,
 	so that the getFolderList will reflect the most recent changes too */
-	groupwise_sync_all (folder, FALSE, error);
+	groupwise_sync_all (folder, FALSE, cancellable, error);
 
 	if (((CamelOfflineStore *) gw_store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
 		g_warning ("In offline mode. Cannot refresh!!!\n");
@@ -1432,7 +1466,7 @@ groupwise_refresh_folder (CamelFolder *folder, GError **error)
 
 	camel_service_lock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
-	if (!camel_groupwise_store_connected (gw_store, error))
+	if (!camel_groupwise_store_connected (gw_store, cancellable, error))
 		goto end1;
 
 	if (!strcmp (full_name, "Trash")) {
@@ -1513,7 +1547,7 @@ groupwise_refresh_folder (CamelFolder *folder, GError **error)
 		g_object_unref (container);
 
 		if (list)
-			gw_update_cache (folder, list, error, FALSE);
+			gw_update_cache (folder, list, FALSE, cancellable, error);
 
 		/* update the new_sync_time to summary */
 		update_summary_string (folder, new_sync_time);
@@ -1616,7 +1650,11 @@ groupwise_folder_set_threading_data (CamelGroupwiseMessageInfo *mi, EGwItem *ite
 
 /* Update the GroupWise cache with the list of items passed. should happen in thread. */
 static void
-gw_update_cache (CamelFolder *folder, GList *list, GError **error, gboolean uid_flag)
+gw_update_cache (CamelFolder *folder,
+                 GList *list,
+                 gboolean uid_flag,
+                 GCancellable *cancellable,
+                 GError **error)
 {
 	CamelGroupwiseMessageInfo *mi = NULL;
 	CamelMessageInfo *pmi = NULL;
@@ -1667,7 +1705,8 @@ gw_update_cache (CamelFolder *folder, GList *list, GError **error, gboolean uid_
 	}
 
 	camel_operation_start (
-		NULL, _("Fetching summary information for new messages in %s"),
+		cancellable,
+		_("Fetching summary information for new messages in %s"),
 		camel_folder_get_name (folder));
 
 	for (; item_list != NULL; item_list = g_list_next (item_list) ) {
@@ -1692,7 +1731,8 @@ gw_update_cache (CamelFolder *folder, GList *list, GError **error, gboolean uid_
 		} else
 			id = (gchar *) item_list->data;
 
-		camel_operation_progress (NULL, (100*i)/total_items);
+		camel_operation_progress (
+			cancellable, (i * 100) / total_items);
 
 		if (folder_needs_caching)
 			status = e_gw_connection_get_item (cnc, container_id, id, GET_ITEM_VIEW_WITH_CACHE, &item);
@@ -1848,7 +1888,7 @@ gw_update_cache (CamelFolder *folder, GList *list, GError **error, gboolean uid_
 
 						CAMEL_GROUPWISE_FOLDER_REC_LOCK (folder, cache_lock);
 						if ((cache_stream = camel_data_cache_add (gw_folder->cache, "cache", id, NULL))) {
-								if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *) mail_msg,	cache_stream, NULL) == -1 || camel_stream_flush (cache_stream, NULL) == -1)
+								if (camel_data_wrapper_write_to_stream ((CamelDataWrapper *) mail_msg,	cache_stream, cancellable, NULL) == -1 || camel_stream_flush (cache_stream, cancellable, NULL) == -1)
 										camel_data_cache_remove (gw_folder->cache, "cache", id, NULL);
 								g_object_unref (cache_stream);
 						}
@@ -1862,7 +1902,9 @@ gw_update_cache (CamelFolder *folder, GList *list, GError **error, gboolean uid_
 		i++;
 		g_object_unref (item);
 	}
-	camel_operation_end (NULL);
+
+	camel_operation_end (cancellable);
+
 	g_free (container_id);
 	g_string_free (str_to, TRUE);
 	g_string_free (str_cc, TRUE);
@@ -1905,7 +1947,10 @@ get_from_from_org (EGwItemOrganizer *org)
 
 /* Update summary, if there is none existing, create one */
 void
-gw_update_summary (CamelFolder *folder, GList *list,GError **error)
+gw_update_summary (CamelFolder *folder,
+                   GList *list,
+                   GCancellable *cancellable,
+                   GError **error)
 {
 	CamelGroupwiseMessageInfo *mi = NULL;
 	CamelGroupwiseStore *gw_store;
@@ -2204,7 +2249,7 @@ groupwise_folder_item_to_msg ( CamelFolder *folder,
 	msg = camel_mime_message_new ();
 	if (has_mime_822 && body) {
 		temp_stream = camel_stream_mem_new_with_buffer (body, body_len);
-		if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) msg, temp_stream, error) == -1) {
+		if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) msg, temp_stream, NULL, error) == -1) {
 			g_object_unref (msg);
 			g_object_unref (temp_stream);
 			msg = NULL;
@@ -2415,7 +2460,10 @@ end:
 }
 
 static void
-gw_update_all_items (CamelFolder *folder, GList *item_list, GError **error)
+gw_update_all_items (CamelFolder *folder,
+                     GList *item_list,
+                     GCancellable *cancellable,
+                     GError **error)
 {
 	CamelGroupwiseFolder *gw_folder = CAMEL_GROUPWISE_FOLDER (folder);
 	GPtrArray *summary = NULL;
@@ -2460,7 +2508,7 @@ gw_update_all_items (CamelFolder *folder, GList *item_list, GError **error)
 		parent_store = camel_folder_get_parent_store (folder);
 
 		camel_service_lock (CAMEL_SERVICE (parent_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-		gw_update_cache (folder, item_list, error, TRUE);
+		gw_update_cache (folder, item_list, TRUE, cancellable, error);
 		camel_service_unlock (CAMEL_SERVICE (parent_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
 		g_list_foreach (item_list, (GFunc)g_free, NULL);
@@ -2471,9 +2519,12 @@ gw_update_all_items (CamelFolder *folder, GList *item_list, GError **error)
 }
 
 static gboolean
-groupwise_append_message (CamelFolder *folder, CamelMimeMessage *message,
-		const CamelMessageInfo *info, gchar **appended_uid,
-		GError **error)
+groupwise_append_message (CamelFolder *folder,
+                          CamelMimeMessage *message,
+                          const CamelMessageInfo *info,
+                          gchar **appended_uid,
+                          GCancellable *cancellable,
+                          GError **error)
 {
 	const gchar *container_id = NULL;
 	CamelGroupwiseStore *gw_store;
@@ -2508,7 +2559,7 @@ groupwise_append_message (CamelFolder *folder, CamelMimeMessage *message,
 	offline = CAMEL_OFFLINE_STORE (parent_store);
 
 	if (offline->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
-		camel_groupwise_journal_append ((CamelGroupwiseJournal *) ((CamelGroupwiseFolder *)folder)->journal, message, info, appended_uid, error);
+		camel_groupwise_journal_append ((CamelGroupwiseJournal *) ((CamelGroupwiseFolder *)folder)->journal, message, info, appended_uid, cancellable, error);
 		return FALSE;
 	}
 	cnc = cnc_lookup (gw_store->priv);
@@ -2587,9 +2638,13 @@ uid_compar (gconstpointer va, gconstpointer vb)
 
 /* move messages */
 static gboolean
-groupwise_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
-		CamelFolder *destination, GPtrArray **transferred_uids,
-		gboolean delete_originals, GError **error)
+groupwise_transfer_messages_to (CamelFolder *source,
+                                GPtrArray *uids,
+                                CamelFolder *destination,
+                                GPtrArray **transferred_uids,
+                                gboolean delete_originals,
+                                GCancellable *cancellable,
+                                GError **error)
 {
 	gint count, index = 0;
 	GList *item_ids = NULL;
@@ -2614,7 +2669,7 @@ groupwise_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
 	gw_store = CAMEL_GROUPWISE_STORE (source_parent_store);
 	offline = CAMEL_OFFLINE_STORE (destination_parent_store);
 
-	if (destination == camel_store_get_trash (source_parent_store, NULL))
+	if (destination == camel_store_get_trash (source_parent_store, cancellable, NULL))
 		destination_is_trash = TRUE;
 	else
 		destination_is_trash = FALSE;
@@ -2655,10 +2710,10 @@ groupwise_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
 			if (!(info = camel_folder_summary_uid (source->summary, uids->pdata[i])))
 				continue;
 
-			if (!(message = groupwise_folder_get_message (source, camel_message_info_uid (info), error)))
+			if (!(message = groupwise_folder_get_message (source, camel_message_info_uid (info), cancellable, error)))
 				break;
 
-			success = camel_groupwise_journal_transfer (journal, (CamelGroupwiseFolder *)source, message, info, uids->pdata[i], NULL, error);
+			success = camel_groupwise_journal_transfer (journal, (CamelGroupwiseFolder *)source, message, info, uids->pdata[i], NULL, cancellable, error);
 			g_object_unref (message);
 
 			if (!success)
@@ -2788,7 +2843,7 @@ groupwise_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
 
 	/* Refresh the destination folder, if its not refreshed already */
 	if (gw_store->current_folder != destination )
-		camel_folder_refresh_info (destination, error);
+		camel_folder_refresh_info (destination, cancellable, error);
 
 	camel_folder_summary_touch (source->summary);
 	camel_folder_summary_touch (destination->summary);
@@ -2801,7 +2856,9 @@ groupwise_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
 }
 
 static gboolean
-groupwise_expunge (CamelFolder *folder, GError **error)
+groupwise_expunge (CamelFolder *folder,
+                   GCancellable *cancellable,
+                   GError **error)
 {
 	CamelGroupwiseStore *gw_store;
 	CamelGroupwiseFolder *gw_folder;
diff --git a/camel/providers/groupwise/camel-groupwise-folder.h b/camel/providers/groupwise/camel-groupwise-folder.h
index f8c5c8c..c8e8b85 100644
--- a/camel/providers/groupwise/camel-groupwise-folder.h
+++ b/camel/providers/groupwise/camel-groupwise-folder.h
@@ -75,11 +75,16 @@ struct _CamelGroupwiseFolderClass {
 	CamelOfflineFolderClass parent_class;
 };
 
-GType camel_groupwise_folder_get_type (void);
-
-/* implemented */
-CamelFolder * camel_gw_folder_new (CamelStore *store, const gchar *folder_dir, const gchar *folder_name, GError **error);
-void gw_update_summary ( CamelFolder *folder, GList *item_list,GError **error);
+GType		camel_groupwise_folder_get_type	(void);
+CamelFolder *	camel_gw_folder_new		(CamelStore *store,
+						 const gchar *folder_dir,
+						 const gchar *folder_name,
+						 GCancellable *cancellable,
+						 GError **error);
+void		gw_update_summary		(CamelFolder *folder,
+						 GList *item_list,
+						 GCancellable *cancellable,
+						 GError **error);
 
 G_END_DECLS
 
diff --git a/camel/providers/groupwise/camel-groupwise-journal.c b/camel/providers/groupwise/camel-groupwise-journal.c
index 1734d9e..07a2601 100644
--- a/camel/providers/groupwise/camel-groupwise-journal.c
+++ b/camel/providers/groupwise/camel-groupwise-journal.c
@@ -44,7 +44,7 @@
 static void groupwise_entry_free (CamelOfflineJournal *journal, CamelDListNode *entry);
 static CamelDListNode *groupwise_entry_load (CamelOfflineJournal *journal, FILE *in);
 static gint groupwise_entry_write (CamelOfflineJournal *journal, CamelDListNode *entry, FILE *out);
-static gint groupwise_entry_play (CamelOfflineJournal *journal, CamelDListNode *entry, GError **error);
+static gint groupwise_entry_play (CamelOfflineJournal *journal, CamelDListNode *entry, GCancellable *cancellable, GError **error);
 
 G_DEFINE_TYPE (CamelGroupwiseJournal, camel_groupwise_journal, CAMEL_TYPE_OFFLINE_JOURNAL)
 
@@ -156,7 +156,10 @@ gw_message_info_dup_to (CamelMessageInfoBase *dest, CamelMessageInfoBase *src)
 }
 
 static gint
-groupwise_entry_play_append (CamelOfflineJournal *journal, CamelGroupwiseJournalEntry *entry, GError **error)
+groupwise_entry_play_append (CamelOfflineJournal *journal,
+                             CamelGroupwiseJournalEntry *entry,
+                             GCancellable *cancellable,
+                             GError **error)
 {
 	CamelGroupwiseFolder *gw_folder = (CamelGroupwiseFolder *) journal->folder;
 	CamelFolder *folder = journal->folder;
@@ -172,7 +175,7 @@ groupwise_entry_play_append (CamelOfflineJournal *journal, CamelGroupwiseJournal
 	}
 
 	message = camel_mime_message_new ();
-	if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) message, stream, error) == -1) {
+	if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) message, stream, cancellable, error) == -1) {
 		g_object_unref (message);
 		g_object_unref (stream);
 		goto done;
@@ -185,7 +188,7 @@ groupwise_entry_play_append (CamelOfflineJournal *journal, CamelGroupwiseJournal
 		info = camel_message_info_new (NULL);
 	}
 
-	success = camel_folder_append_message (folder, message, info, NULL, error);
+	success = camel_folder_append_message (folder, message, info, NULL, cancellable, error);
 	camel_message_info_free (info);
 	g_object_unref (message);
 
@@ -198,7 +201,10 @@ done:
 }
 
 static gint
-groupwise_entry_play_transfer (CamelOfflineJournal *journal, CamelGroupwiseJournalEntry *entry, GError **error)
+groupwise_entry_play_transfer (CamelOfflineJournal *journal,
+                               CamelGroupwiseJournalEntry *entry,
+                               GCancellable *cancellable,
+                               GError **error)
 {
 	CamelGroupwiseFolder *gw_folder = (CamelGroupwiseFolder *) journal->folder;
 	CamelFolder *folder = journal->folder;
@@ -217,11 +223,11 @@ groupwise_entry_play_transfer (CamelOfflineJournal *journal, CamelGroupwiseJourn
 	}
 
 	name = camel_groupwise_store_folder_lookup ((CamelGroupwiseStore *) parent_store, entry->source_container);
-	if (name && (src = camel_store_get_folder (parent_store, name, 0, error))) {
+	if (name && (src = camel_store_get_folder (parent_store, name, 0, cancellable, error))) {
 		uids = g_ptr_array_sized_new (1);
 		g_ptr_array_add (uids, entry->original_uid);
 
-		if (camel_folder_transfer_messages_to (src, uids, folder, &xuids, FALSE, error)) {
+		if (camel_folder_transfer_messages_to (src, uids, folder, &xuids, FALSE, cancellable, error)) {
 			real = (CamelGroupwiseMessageInfo *) camel_folder_summary_uid (folder->summary, xuids->pdata[0]);
 
 			/* transfer all the system flags, user flags/tags, etc */
@@ -257,15 +263,18 @@ groupwise_entry_play_transfer (CamelOfflineJournal *journal, CamelGroupwiseJourn
 }
 
 static gint
-groupwise_entry_play (CamelOfflineJournal *journal, CamelDListNode *entry, GError **error)
+groupwise_entry_play (CamelOfflineJournal *journal,
+                      CamelDListNode *entry,
+                      GCancellable *cancellable,
+                      GError **error)
 {
 	CamelGroupwiseJournalEntry *groupwise_entry = (CamelGroupwiseJournalEntry *) entry;
 
 	switch (groupwise_entry->type) {
 	case CAMEL_GROUPWISE_JOURNAL_ENTRY_APPEND:
-		return groupwise_entry_play_append (journal, groupwise_entry, error);
+		return groupwise_entry_play_append (journal, groupwise_entry, cancellable, error);
 	case CAMEL_GROUPWISE_JOURNAL_ENTRY_TRANSFER:
-		return groupwise_entry_play_transfer (journal, groupwise_entry, error);
+		return groupwise_entry_play_transfer (journal, groupwise_entry, cancellable, error);
 	default:
 		g_assert_not_reached ();
 		return -1;
@@ -286,8 +295,12 @@ camel_groupwise_journal_new (CamelGroupwiseFolder *folder, const gchar *filename
 }
 
 static gboolean
-update_cache (CamelGroupwiseJournal *groupwise_journal, CamelMimeMessage *message,
-	      const CamelMessageInfo *mi, gchar **updated_uid, GError **error)
+update_cache (CamelGroupwiseJournal *groupwise_journal,
+              CamelMimeMessage *message,
+              const CamelMessageInfo *mi,
+              gchar **updated_uid,
+              GCancellable *cancellable,
+              GError **error)
 {
 	CamelOfflineJournal *journal = (CamelOfflineJournal *) groupwise_journal;
 	CamelGroupwiseFolder *groupwise_folder = (CamelGroupwiseFolder *) journal->folder;
@@ -314,8 +327,8 @@ update_cache (CamelGroupwiseJournal *groupwise_journal, CamelMimeMessage *messag
 	}
 
 	if (camel_data_wrapper_write_to_stream (
-		(CamelDataWrapper *) message, cache, error) == -1
-	    || camel_stream_flush (cache, error) == -1) {
+		(CamelDataWrapper *) message, cache, cancellable, error) == -1
+	    || camel_stream_flush (cache, cancellable, error) == -1) {
 		g_prefix_error (
 			error, _("Cannot append message in offline mode: "));
 		camel_data_cache_remove (groupwise_folder->cache, "cache", uid, NULL);
@@ -344,14 +357,18 @@ update_cache (CamelGroupwiseJournal *groupwise_journal, CamelMimeMessage *messag
 }
 
 gboolean
-camel_groupwise_journal_append (CamelGroupwiseJournal *groupwise_journal, CamelMimeMessage *message,
-				const CamelMessageInfo *mi, gchar **appended_uid, GError **error)
+camel_groupwise_journal_append (CamelGroupwiseJournal *groupwise_journal,
+                                CamelMimeMessage *message,
+                                const CamelMessageInfo *mi,
+                                gchar **appended_uid,
+                                GCancellable *cancellable,
+                                GError **error)
 {
 	CamelOfflineJournal *journal = (CamelOfflineJournal *) groupwise_journal;
 	CamelGroupwiseJournalEntry *entry;
 	gchar *uid;
 
-	if (!update_cache (groupwise_journal, message, mi, &uid, error))
+	if (!update_cache (groupwise_journal, message, mi, &uid, cancellable, error))
 		return FALSE;
 
 	entry = g_new (CamelGroupwiseJournalEntry, 1);
@@ -367,10 +384,14 @@ camel_groupwise_journal_append (CamelGroupwiseJournal *groupwise_journal, CamelM
 }
 
 gboolean
-camel_groupwise_journal_transfer (CamelGroupwiseJournal *groupwise_journal, CamelGroupwiseFolder *source_folder,
-				  CamelMimeMessage *message,  const CamelMessageInfo *mi,
-				  const gchar *original_uid, gchar **transferred_uid,
-				  GError **error)
+camel_groupwise_journal_transfer (CamelGroupwiseJournal *groupwise_journal,
+                                  CamelGroupwiseFolder *source_folder,
+                                  CamelMimeMessage *message,
+                                  const CamelMessageInfo *mi,
+                                  const gchar *original_uid,
+                                  gchar **transferred_uid,
+                                  GCancellable *cancellable,
+                                  GError **error)
 {
 	CamelOfflineJournal *journal = (CamelOfflineJournal *) groupwise_journal;
 	CamelGroupwiseStore *gw_store;
@@ -381,7 +402,7 @@ camel_groupwise_journal_transfer (CamelGroupwiseJournal *groupwise_journal, Came
 	parent_store = camel_folder_get_parent_store (journal->folder);
 	gw_store = CAMEL_GROUPWISE_STORE (parent_store);
 
-	if (!update_cache (groupwise_journal, message, mi, &uid, error))
+	if (!update_cache (groupwise_journal, message, mi, &uid, cancellable, error))
 		return FALSE;
 
 	entry = g_new (CamelGroupwiseJournalEntry, 1);
diff --git a/camel/providers/groupwise/camel-groupwise-journal.h b/camel/providers/groupwise/camel-groupwise-journal.h
index a58e31f..b32fe5a 100644
--- a/camel/providers/groupwise/camel-groupwise-journal.h
+++ b/camel/providers/groupwise/camel-groupwise-journal.h
@@ -78,15 +78,25 @@ struct _CamelGroupwiseJournalClass {
 
 };
 
-GType camel_groupwise_journal_get_type (void);
-
-CamelOfflineJournal *camel_groupwise_journal_new (struct _CamelGroupwiseFolder *folder, const gchar *filename);
-
-/* interfaces for adding a journal entry */
-gboolean camel_groupwise_journal_append (CamelGroupwiseJournal *journal, CamelMimeMessage *message, const CamelMessageInfo *mi,
-				     gchar **appended_uid, GError **error);
-gboolean camel_groupwise_journal_transfer (CamelGroupwiseJournal *journal, CamelGroupwiseFolder *source_folder, CamelMimeMessage *message,
-				       const CamelMessageInfo *mi, const gchar *orginal_uid, gchar **transferred_uid, GError **error);
+GType		camel_groupwise_journal_get_type (void);
+CamelOfflineJournal *
+		camel_groupwise_journal_new	(CamelGroupwiseFolder *folder,
+						 const gchar *filename);
+gboolean	camel_groupwise_journal_append	(CamelGroupwiseJournal *journal,
+						 CamelMimeMessage *message,
+						 const CamelMessageInfo *mi,
+						 gchar **appended_uid,
+						 GCancellable *cancellable,
+						 GError **error);
+gboolean	camel_groupwise_journal_transfer
+						(CamelGroupwiseJournal *journal,
+						 CamelGroupwiseFolder *source_folder,
+						 CamelMimeMessage *message,
+						 const CamelMessageInfo *mi,
+						 const gchar *orginal_uid,
+						 gchar **transferred_uid,
+						 GCancellable *cancellable,
+						 GError **error);
 
 G_END_DECLS
 
diff --git a/camel/providers/groupwise/camel-groupwise-store.c b/camel/providers/groupwise/camel-groupwise-store.c
index 1dc4297..915f337 100644
--- a/camel/providers/groupwise/camel-groupwise-store.c
+++ b/camel/providers/groupwise/camel-groupwise-store.c
@@ -75,8 +75,8 @@ struct _CamelGroupwiseStorePrivate {
 };
 
 extern CamelServiceAuthType camel_groupwise_password_authtype; /*for the query_auth_types function*/
-static CamelFolderInfo *convert_to_folder_info (CamelGroupwiseStore *store, EGwContainer *container, const gchar *url, GError **error);
-static gboolean groupwise_folders_sync (CamelGroupwiseStore *store, GError **error);
+static CamelFolderInfo *convert_to_folder_info (CamelGroupwiseStore *store, EGwContainer *container, const gchar *url, GCancellable *cancellable, GError **error);
+static gboolean groupwise_folders_sync (CamelGroupwiseStore *store, GCancellable *cancellable, GError **error);
 static gint match_path (const gchar *path, const gchar *name);
 
 G_DEFINE_TYPE (CamelGroupwiseStore, camel_groupwise_store, CAMEL_TYPE_OFFLINE_STORE)
@@ -171,7 +171,9 @@ groupwise_compare_folder_name (gconstpointer a, gconstpointer b)
 }
 
 static gboolean
-groupwise_auth_loop (CamelService *service, GError **error)
+groupwise_auth_loop (CamelService *service,
+                     GCancellable *cancellable,
+                     GError **error)
 {
 	CamelSession *session = camel_service_get_session (service);
 	CamelStore *store = CAMEL_STORE (service);
@@ -239,7 +241,9 @@ groupwise_auth_loop (CamelService *service, GError **error)
 }
 
 static gboolean
-check_for_connection (CamelService *service, GError **error)
+check_for_connection (CamelService *service,
+                      GCancellable *cancellable,
+                      GError **error)
 {
 	CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (service);
 	CamelGroupwiseStorePrivate *priv = groupwise_store->priv;
@@ -249,10 +253,10 @@ check_for_connection (CamelService *service, GError **error)
 	memset (&hints, 0, sizeof (hints));
 	hints.ai_socktype = SOCK_STREAM;
 	hints.ai_family = PF_UNSPEC;
-	ai = camel_getaddrinfo(priv->server_name, "groupwise", &hints, &local_error);
+	ai = camel_getaddrinfo(priv->server_name, "groupwise", &hints, cancellable, &local_error);
 	if (ai == NULL && priv->port != NULL && g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
 		g_clear_error (&local_error);
-		ai = camel_getaddrinfo (priv->server_name, priv->port, &hints, &local_error);
+		ai = camel_getaddrinfo (priv->server_name, priv->port, &hints, cancellable, &local_error);
 	}
 
 	if (ai == NULL) {
@@ -285,7 +289,9 @@ groupwise_store_set_current_folder (CamelGroupwiseStore *groupwise_store, CamelF
 }
 
 static gboolean
-groupwise_connect (CamelService *service, GError **error)
+groupwise_connect (CamelService *service,
+                   GCancellable *cancellable,
+                   GError **error)
 {
 	CamelGroupwiseStore *store = CAMEL_GROUPWISE_STORE (service);
 	CamelGroupwiseStorePrivate *priv = store->priv;
@@ -313,7 +319,7 @@ groupwise_connect (CamelService *service, GError **error)
 		return TRUE;
 	}
 
-	if (!check_for_connection (service, error) || !groupwise_auth_loop (service, error)) {
+	if (!check_for_connection (service, cancellable, error) || !groupwise_auth_loop (service, cancellable, error)) {
 		camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
 		camel_service_disconnect (service, TRUE, NULL);
 		return FALSE;
@@ -404,7 +410,10 @@ groupwise_disconnect_cleanup (CamelService *service, gboolean clean, GError **er
 #endif
 
 static gboolean
-groupwise_disconnect (CamelService *service, gboolean clean, GError **error)
+groupwise_disconnect (CamelService *service,
+                      gboolean clean,
+                      GCancellable *cancellable,
+                      GError **error)
 {
 	CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (service);
 
@@ -425,7 +434,9 @@ groupwise_disconnect (CamelService *service, gboolean clean, GError **error)
 }
 
 static  GList*
-groupwise_store_query_auth_types (CamelService *service, GError **error)
+groupwise_store_query_auth_types (CamelService *service,
+                                  GCancellable *cancellable,
+                                  GError **error)
 {
 	GList *auth_types = NULL;
 
@@ -532,7 +543,11 @@ groupwise_forget_folder (CamelGroupwiseStore *gw_store, const gchar *folder_name
 }
 
 static CamelFolder *
-groupwise_get_folder_from_disk (CamelStore *store, const gchar *folder_name, guint32 flags, GError **error)
+groupwise_get_folder_from_disk (CamelStore *store,
+                                const gchar *folder_name,
+                                guint32 flags,
+                                GCancellable *cancellable,
+                                GError **error)
 {
 	CamelGroupwiseStore *gw_store = CAMEL_GROUPWISE_STORE (store);
 	CamelGroupwiseStorePrivate *priv = gw_store->priv;
@@ -551,14 +566,18 @@ groupwise_get_folder_from_disk (CamelStore *store, const gchar *folder_name, gui
 		return NULL;
 	}
 
-	folder = camel_gw_folder_new (store, folder_name, folder_dir, error);
+	folder = camel_gw_folder_new (store, folder_name, folder_dir, cancellable, error);
 	g_free (folder_dir);
 
 	return folder;
 }
 
 static CamelFolder *
-groupwise_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError **error)
+groupwise_get_folder (CamelStore *store,
+                      const gchar *folder_name,
+                      guint32 flags,
+                      GCancellable *cancellable,
+                      GError **error)
 {
 	CamelGroupwiseStore *gw_store = CAMEL_GROUPWISE_STORE (store);
 	CamelGroupwiseStorePrivate *priv = gw_store->priv;
@@ -575,7 +594,7 @@ groupwise_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags
 	GError *local_error = NULL;
 
 	folder = groupwise_get_folder_from_disk (
-		store, folder_name, flags, &local_error);
+		store, folder_name, flags, cancellable, &local_error);
 	if (folder) {
 		groupwise_store_set_current_folder (gw_store, folder);
 		return folder;
@@ -592,13 +611,13 @@ groupwise_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags
 
 	groupwise_store_set_current_folder (gw_store, NULL);
 
-	if (!camel_groupwise_store_connected (gw_store, error)) {
+	if (!camel_groupwise_store_connected (gw_store, cancellable, error)) {
 		camel_service_unlock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 		return NULL;
 	}
 
 	if (!E_IS_GW_CONNECTION ( priv->cnc)) {
-		if (!groupwise_connect (CAMEL_SERVICE (store), error)) {
+		if (!groupwise_connect (CAMEL_SERVICE (store), cancellable, error)) {
 			camel_service_unlock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 			return NULL;
 		}
@@ -609,7 +628,7 @@ groupwise_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags
 	storage_path = g_strdup_printf("%s/folders", priv->storage_path);
 	folder_dir = e_path_to_physical (storage_path, folder_name);
 	g_free (storage_path);
-	folder = camel_gw_folder_new (store, folder_name, folder_dir, NULL);
+	folder = camel_gw_folder_new (store, folder_name, folder_dir, cancellable, NULL);
 	if (!folder) {
 		camel_service_unlock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 		g_set_error (
@@ -651,7 +670,8 @@ groupwise_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags
 		}
 
 		camel_operation_start (
-			NULL, _("Fetching summary information for new messages in %s"),
+			cancellable,
+			_("Fetching summary information for new messages in %s"),
 			camel_folder_get_name (folder));
 		camel_folder_summary_clear (folder->summary);
 
@@ -669,15 +689,16 @@ groupwise_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags
 				count += CURSOR_ITEM_LIMIT;
 
 				if (total > 0) {
-						d(printf ("Doing readcursor : [total: %d] [count: %d]\n", total, count));
+					d(printf ("Doing readcursor : [total: %d] [count: %d]\n", total, count));
 
-						if (count > total)
-								count = total;
+					if (count > total)
+						count = total;
 
-						camel_operation_progress (NULL, (100*count)/total);
+					camel_operation_progress (
+						cancellable, (100*count)/total);
 				}
 
-				gw_update_summary (folder, list,  error);
+				gw_update_summary (folder, list, cancellable, error);
 
 				/* For shared-folders created by the user, we don't get the total number of messages,
 				in the getFolderList call. So, we need to wait until an empty list is returned in the
@@ -693,7 +714,7 @@ groupwise_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags
 
 		e_gw_connection_destroy_cursor (priv->cnc, container_id, cursor);
 
-		camel_operation_end (NULL);
+		camel_operation_end (cancellable);
 	}
 	if (done && all_ok) {
 		if (summary->time_string)
@@ -712,7 +733,11 @@ groupwise_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags
 }
 
 gboolean
-gw_store_reload_folder (CamelGroupwiseStore *gw_store, CamelFolder *folder, guint32 flags, GError **error)
+gw_store_reload_folder (CamelGroupwiseStore *gw_store,
+                        CamelFolder *folder,
+                        guint32 flags,
+                        GCancellable *cancellable,
+                        GError **error)
 {
 	CamelGroupwiseStorePrivate *priv = gw_store->priv;
 	CamelGroupwiseSummary *summary;
@@ -732,13 +757,13 @@ gw_store_reload_folder (CamelGroupwiseStore *gw_store, CamelFolder *folder, guin
 
 	camel_service_lock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
-	if (!camel_groupwise_store_connected (gw_store, error)) {
+	if (!camel_groupwise_store_connected (gw_store, cancellable, error)) {
 		camel_service_unlock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 		return FALSE;
 	}
 
 	if (!E_IS_GW_CONNECTION ( priv->cnc)) {
-		if (!groupwise_connect (CAMEL_SERVICE ((CamelStore*)gw_store), error)) {
+		if (!groupwise_connect (CAMEL_SERVICE ((CamelStore*)gw_store), cancellable, error)) {
 			camel_service_unlock (CAMEL_SERVICE (gw_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 			return FALSE;
 		}
@@ -776,7 +801,8 @@ gw_store_reload_folder (CamelGroupwiseStore *gw_store, CamelFolder *folder, guin
 			}
 
 			camel_operation_start (
-				NULL, _("Fetching summary information for new messages in %s"),
+				cancellable,
+				_("Fetching summary information for new messages in %s"),
 				camel_folder_get_name (folder));
 
 			while (!done) {
@@ -791,7 +817,7 @@ gw_store_reload_folder (CamelGroupwiseStore *gw_store, CamelFolder *folder, guin
 								error, CAMEL_SERVICE_ERROR,
 								CAMEL_SERVICE_ERROR_INVALID,
 								_("Authentication failed"));
-							camel_operation_end (NULL);
+							camel_operation_end (cancellable);
 							g_free (container_id);
 							return FALSE;
 					}
@@ -805,10 +831,11 @@ gw_store_reload_folder (CamelGroupwiseStore *gw_store, CamelFolder *folder, guin
 							if (count > total)
 									count = total;
 
-							camel_operation_progress (NULL, (100*count)/total);
+							camel_operation_progress (
+								cancellable, (100 * count) / total);
 					}
 
-					gw_update_summary (folder, list,  error);
+					gw_update_summary (folder, list, cancellable, error);
 
 					/* For shared-folders created by the user, we don't get the total number of messages,
 					   in the getFolderList call. So, we need to wait until an empty list is returned in the
@@ -824,7 +851,7 @@ gw_store_reload_folder (CamelGroupwiseStore *gw_store, CamelFolder *folder, guin
 
 			e_gw_connection_destroy_cursor (priv->cnc, container_id, cursor);
 
-			camel_operation_end (NULL);
+			camel_operation_end (cancellable);
 	}
 
 	if (done) {
@@ -843,7 +870,11 @@ gw_store_reload_folder (CamelGroupwiseStore *gw_store, CamelFolder *folder, guin
 }
 
 static CamelFolderInfo *
-convert_to_folder_info (CamelGroupwiseStore *store, EGwContainer *container, const gchar *url, GError **error)
+convert_to_folder_info (CamelGroupwiseStore *store,
+                        EGwContainer *container,
+                        const gchar *url,
+                        GCancellable *cancellable,
+                        GError **error)
 {
 	const gchar *name = NULL, *id = NULL, *parent = NULL;
 	gchar *par_name = NULL;
@@ -934,7 +965,7 @@ convert_to_folder_info (CamelGroupwiseStore *store, EGwContainer *container, con
 	if (store->current_folder
 	    && !strcmp (camel_folder_get_full_name (store->current_folder), fi->full_name)
 	    && type != E_GW_CONTAINER_TYPE_INBOX) {
-		CAMEL_FOLDER_GET_CLASS (store->current_folder)->refresh_info (store->current_folder, error);
+		CAMEL_FOLDER_GET_CLASS (store->current_folder)->refresh_info (store->current_folder, cancellable, error);
 	}
 	return fi;
 }
@@ -947,7 +978,9 @@ get_folders_free (gpointer k, gpointer v, gpointer d)
 }
 
 static gboolean
-groupwise_folders_sync (CamelGroupwiseStore *store, GError **error)
+groupwise_folders_sync (CamelGroupwiseStore *store,
+                        GCancellable *cancellable,
+                        GError **error)
 {
 	CamelGroupwiseStorePrivate  *priv = store->priv;
 	gint status;
@@ -1013,7 +1046,7 @@ groupwise_folders_sync (CamelGroupwiseStore *store, GError **error)
 		if ((type == E_GW_CONTAINER_TYPE_CALENDAR) || (type == E_GW_CONTAINER_TYPE_CONTACTS))
 			continue;
 
-		info = convert_to_folder_info (store, E_GW_CONTAINER (folder_list->data), (const gchar *)url, error);
+		info = convert_to_folder_info (store, E_GW_CONTAINER (folder_list->data), (const gchar *)url, cancellable, error);
 		if (info) {
 			hfi = g_hash_table_lookup (present, info->full_name);
 			if (hfi == NULL)
@@ -1103,7 +1136,11 @@ groupwise_get_folder_info_offline (CamelStore *store, const gchar *top,
 }
 
 static CamelFolderInfo *
-groupwise_get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GError **error)
+groupwise_get_folder_info (CamelStore *store,
+                           const gchar *top,
+                           guint32 flags,
+                           GCancellable *cancellable,
+                           GError **error)
 {
 	CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (store);
 	CamelFolderInfo *info = NULL;
@@ -1116,7 +1153,7 @@ groupwise_get_folder_info (CamelStore *store, const gchar *top, guint32 flags, G
 
 	camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
-	if (!groupwise_folders_sync (groupwise_store, error)) {
+	if (!groupwise_folders_sync (groupwise_store, cancellable, error)) {
 		camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 		return NULL;
 	}
@@ -1170,9 +1207,10 @@ create_junk_folder (CamelStore *store)
 
 static CamelFolderInfo*
 groupwise_create_folder (CamelStore *store,
-		const gchar *parent_name,
-		const gchar *folder_name,
-		GError **error)
+                         const gchar *parent_name,
+                         const gchar *folder_name,
+                         GCancellable *cancellable,
+                         GError **error)
 {
 	CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (store);
 	CamelGroupwiseStorePrivate  *priv = groupwise_store->priv;
@@ -1211,7 +1249,7 @@ groupwise_create_folder (CamelStore *store,
 		parent_id = "";
 
 	if (!E_IS_GW_CONNECTION ( priv->cnc)) {
-		if (!groupwise_connect (CAMEL_SERVICE (store), error)) {
+		if (!groupwise_connect (CAMEL_SERVICE (store), cancellable, error)) {
 			return NULL;
 		}
 	}
@@ -1235,8 +1273,9 @@ groupwise_create_folder (CamelStore *store,
 
 static gboolean
 groupwise_delete_folder (CamelStore *store,
-				   const gchar *folder_name,
-				   GError **error)
+                         const gchar *folder_name,
+                         GCancellable *cancellable,
+                         GError **error)
 {
 	CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (store);
 	CamelGroupwiseStorePrivate  *priv = groupwise_store->priv;
@@ -1245,7 +1284,7 @@ groupwise_delete_folder (CamelStore *store,
 
 	camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
-	if (!camel_groupwise_store_connected (groupwise_store, error)) {
+	if (!camel_groupwise_store_connected (groupwise_store, cancellable, error)) {
 		camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 		return FALSE;
 	}
@@ -1273,9 +1312,10 @@ groupwise_delete_folder (CamelStore *store,
 
 static gboolean
 groupwise_rename_folder (CamelStore *store,
-			const gchar *old_name,
-			const gchar *new_name,
-			GError **error)
+                         const gchar *old_name,
+                         const gchar *new_name,
+                         GCancellable *cancellable,
+                         GError **error)
 {
 	CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (store);
 	CamelGroupwiseStorePrivate  *priv = groupwise_store->priv;
@@ -1293,7 +1333,7 @@ groupwise_rename_folder (CamelStore *store,
 
 	camel_service_lock (CAMEL_SERVICE (groupwise_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
-	if (!camel_groupwise_store_connected (groupwise_store, error)) {
+	if (!camel_groupwise_store_connected (groupwise_store, cancellable, error)) {
 		camel_service_unlock (CAMEL_SERVICE (groupwise_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 		return FALSE;
 	}
@@ -1386,9 +1426,13 @@ groupwise_base_url_lookup (CamelGroupwiseStorePrivate *priv)
 }
 
 static CamelFolder *
-groupwise_get_trash (CamelStore *store, GError **error)
+groupwise_get_trash (CamelStore *store,
+                     GCancellable *cancellable,
+                     GError **error)
 {
-	CamelFolder *folder = camel_store_get_folder(store, "Trash", 0, error);
+	CamelFolder *folder;
+
+	folder = camel_store_get_folder(store, "Trash", 0, cancellable, error);
 	if (folder) {
 		CamelObject *object = CAMEL_OBJECT (folder);
 		 gchar *state = g_build_filename((CAMEL_GROUPWISE_STORE(store))->priv->storage_path, "folders", "Trash", "cmeta", NULL);
@@ -1418,7 +1462,9 @@ groupwise_can_refresh_folder (CamelStore *store, CamelFolderInfo *info, GError *
  * online. Based on an equivalient function in IMAP
  */
 gboolean
-camel_groupwise_store_connected (CamelGroupwiseStore *store, GError **error)
+camel_groupwise_store_connected (CamelGroupwiseStore *store,
+                                 GCancellable *cancellable,
+                                 GError **error)
 {
 	if (((CamelOfflineStore *) store)->state == CAMEL_OFFLINE_STORE_NETWORK_AVAIL
 	    && camel_service_connect ((CamelService *)store, error)) {
@@ -1426,7 +1472,7 @@ camel_groupwise_store_connected (CamelGroupwiseStore *store, GError **error)
 		CamelGroupwiseStorePrivate *priv = gw_store->priv;
 
 		if (g_hash_table_size (priv->name_hash) == 0)
-			return groupwise_folders_sync ((CamelGroupwiseStore *) gw_store, error);
+			return groupwise_folders_sync ((CamelGroupwiseStore *) gw_store, cancellable, error);
 
 		return TRUE;
 	}
diff --git a/camel/providers/groupwise/camel-groupwise-store.h b/camel/providers/groupwise/camel-groupwise-store.h
index 2ebda32..7e901c3 100644
--- a/camel/providers/groupwise/camel-groupwise-store.h
+++ b/camel/providers/groupwise/camel-groupwise-store.h
@@ -76,19 +76,31 @@ struct _CamelGroupwiseStoreClass {
 	CamelOfflineStoreClass parent_class;
 };
 
-GType camel_groupwise_store_get_type (void);
-gchar * groupwise_get_name (CamelService *service, gboolean brief);
-
-/*IMplemented*/
-const gchar *camel_groupwise_store_container_id_lookup (CamelGroupwiseStore *gw_store, const gchar *folder_name);
-const gchar *camel_groupwise_store_folder_lookup (CamelGroupwiseStore *gw_store, const gchar *container_id);
-EGwConnection *cnc_lookup (CamelGroupwiseStorePrivate *priv);
-gchar *storage_path_lookup (CamelGroupwiseStorePrivate *priv);
-const gchar *groupwise_base_url_lookup (CamelGroupwiseStorePrivate *priv);
-CamelFolderInfo * create_junk_folder (CamelStore *store);
-gboolean camel_groupwise_store_connected (CamelGroupwiseStore *store, GError **error);
-gboolean gw_store_reload_folder (CamelGroupwiseStore *store, CamelFolder *folder, guint32 flags, GError **error);
-void groupwise_store_set_current_folder (CamelGroupwiseStore *groupwise_store, CamelFolder *folder);
+GType		camel_groupwise_store_get_type	(void);
+gchar *		groupwise_get_name		(CamelService *service,
+						 gboolean brief);
+const gchar *	camel_groupwise_store_container_id_lookup
+						(CamelGroupwiseStore *store,
+						 const gchar *folder_name);
+const gchar *	camel_groupwise_store_folder_lookup
+						(CamelGroupwiseStore *store,
+						 const gchar *container_id);
+EGwConnection *	cnc_lookup			(CamelGroupwiseStorePrivate *priv);
+gchar *		storage_path_lookup		(CamelGroupwiseStorePrivate *priv);
+const gchar *	groupwise_base_url_lookup	(CamelGroupwiseStorePrivate *priv);
+CamelFolderInfo *
+		create_junk_folder		(CamelStore *store);
+gboolean	camel_groupwise_store_connected	(CamelGroupwiseStore *store,
+						 GCancellable *cancellable,
+						 GError **error);
+gboolean	gw_store_reload_folder		(CamelGroupwiseStore *store,
+						 CamelFolder *folder,
+						 guint32 flags,
+						 GCancellable *cancellable,
+						 GError **error);
+void		groupwise_store_set_current_folder
+						(CamelGroupwiseStore *store,
+						 CamelFolder *folder);
 
 G_END_DECLS
 
diff --git a/camel/providers/groupwise/camel-groupwise-summary.c b/camel/providers/groupwise/camel-groupwise-summary.c
index c1a0301..b155ddb 100644
--- a/camel/providers/groupwise/camel-groupwise-summary.c
+++ b/camel/providers/groupwise/camel-groupwise-summary.c
@@ -293,7 +293,9 @@ content_info_to_db (CamelFolderSummary *s, CamelMessageContentInfo *info, CamelM
 }
 
 static gboolean
-gw_info_set_flags (CamelMessageInfo *info, guint32 flags, guint32 set)
+gw_info_set_flags (CamelMessageInfo *info,
+                   guint32 flags,
+                   guint32 set)
 {
 		guint32 old;
 		CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info;
@@ -357,7 +359,10 @@ gw_info_set_flags (CamelMessageInfo *info, guint32 flags, guint32 set)
 }
 
 void
-camel_gw_summary_add_offline (CamelFolderSummary *summary, const gchar *uid, CamelMimeMessage *message, const CamelMessageInfo *info)
+camel_gw_summary_add_offline (CamelFolderSummary *summary,
+                              const gchar *uid,
+                              CamelMimeMessage *message,
+                              const CamelMessageInfo *info)
 {
 	CamelGroupwiseMessageInfo *mi;
 	const CamelFlag *flag;
@@ -388,7 +393,9 @@ camel_gw_summary_add_offline (CamelFolderSummary *summary, const gchar *uid, Cam
 }
 
 void
-camel_gw_summary_add_offline_uncached (CamelFolderSummary *summary, const gchar *uid, const CamelMessageInfo *info)
+camel_gw_summary_add_offline_uncached (CamelFolderSummary *summary,
+                                       const gchar *uid,
+                                       const CamelMessageInfo *info)
 {
 	CamelGroupwiseMessageInfo *mi;
 
diff --git a/camel/providers/groupwise/camel-groupwise-summary.h b/camel/providers/groupwise/camel-groupwise-summary.h
index fbe84b4..c0ed562 100644
--- a/camel/providers/groupwise/camel-groupwise-summary.h
+++ b/camel/providers/groupwise/camel-groupwise-summary.h
@@ -76,16 +76,22 @@ struct _CamelGroupwiseSummary {
 
 struct _CamelGroupwiseSummaryClass {
 	CamelFolderSummaryClass parent_class;
-} ;
-
-GType camel_groupwise_summary_get_type (void);
-
-CamelFolderSummary *camel_groupwise_summary_new (struct _CamelFolder *folder, const gchar *filename);
-
-void camel_gw_summary_add_offline (CamelFolderSummary *summary, const gchar *uid, CamelMimeMessage *messgae, const CamelMessageInfo *info);
+};
 
-void camel_gw_summary_add_offline_uncached (CamelFolderSummary *summary, const gchar *uid, const CamelMessageInfo *info);
-void groupwise_summary_clear (CamelFolderSummary *summary, gboolean uncache);
+GType		camel_groupwise_summary_get_type (void);
+CamelFolderSummary *
+		camel_groupwise_summary_new	(CamelFolder *folder,
+						 const gchar *filename);
+void		camel_gw_summary_add_offline	(CamelFolderSummary *summary,
+						 const gchar *uid,
+						 CamelMimeMessage *messgae,
+						 const CamelMessageInfo *info);
+void		camel_gw_summary_add_offline_uncached
+						(CamelFolderSummary *summary,
+						 const gchar *uid,
+						 const CamelMessageInfo *info);
+void		groupwise_summary_clear		(CamelFolderSummary *summary,
+						 gboolean uncache);
 
 G_END_DECLS
 
diff --git a/camel/providers/groupwise/camel-groupwise-transport.c b/camel/providers/groupwise/camel-groupwise-transport.c
index ebccd13..99e621a 100644
--- a/camel/providers/groupwise/camel-groupwise-transport.c
+++ b/camel/providers/groupwise/camel-groupwise-transport.c
@@ -40,6 +40,7 @@ G_DEFINE_TYPE (CamelGroupwiseTransport, camel_groupwise_transport, CAMEL_TYPE_TR
 
 static gboolean
 groupwise_transport_connect (CamelService *service,
+                             GCancellable *cancellable,
                              GError **error)
 {
 	return TRUE;
@@ -64,6 +65,7 @@ groupwise_send_to (CamelTransport *transport,
                    CamelMimeMessage *message,
                    CamelAddress *from,
                    CamelAddress *recipients,
+                   GCancellable *cancellable,
                    GError **error)
 {
 	CamelService *service;
@@ -92,7 +94,7 @@ groupwise_send_to (CamelTransport *transport,
 				    CAMEL_URL_HIDE_PARAMS   |
 				    CAMEL_URL_HIDE_AUTH) );
 
-	camel_operation_start (NULL, _("Sending Message") );
+	camel_operation_start (cancellable, _("Sending Message") );
 
 	/*camel groupwise store and cnc*/
 	store = camel_session_get_store (service->session, url, NULL);
@@ -111,7 +113,7 @@ groupwise_send_to (CamelTransport *transport,
 	cnc = cnc_lookup (priv);
 	if (!cnc) {
 		g_warning ("||| Eh!!! Failure |||\n");
-		camel_operation_end (NULL);
+		camel_operation_end (cancellable);
 		g_set_error (
 			error, CAMEL_SERVICE_ERROR,
 			CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
@@ -138,7 +140,7 @@ groupwise_send_to (CamelTransport *transport,
 	status = e_gw_connection_send_item (cnc, item, &sent_item_list);
 	if (status != E_GW_CONNECTION_STATUS_OK) {
 		g_warning (" Error Sending mail");
-		camel_operation_end (NULL);
+		camel_operation_end (cancellable);
 		e_gw_item_set_link_info (item, NULL);
 		g_object_unref (item);
 		if (temp_item)
@@ -167,7 +169,7 @@ groupwise_send_to (CamelTransport *transport,
 		g_object_unref (temp_item);
 	g_object_unref (item);
 
-	camel_operation_end (NULL);
+	camel_operation_end (cancellable);
 
 	return TRUE;
 }
diff --git a/camel/providers/groupwise/camel-groupwise-utils.c b/camel/providers/groupwise/camel-groupwise-utils.c
index 2372914..c6bf0f6 100644
--- a/camel/providers/groupwise/camel-groupwise-utils.c
+++ b/camel/providers/groupwise/camel-groupwise-utils.c
@@ -424,7 +424,6 @@ camel_groupwise_util_item_from_message (EGwConnection *cnc, CamelMimeMessage *me
 	mp = (CamelMultipart *)camel_medium_get_content (CAMEL_MEDIUM (message));
 	if (!mp) {
 		g_warning ("ERROR: Could not get content object");
-		camel_operation_end (NULL);
 		return NULL;
 	}
 
@@ -465,14 +464,14 @@ camel_groupwise_util_item_from_message (EGwConnection *cnc, CamelMimeMessage *me
 				filtered_stream = g_object_ref (content);
 			}
 
-			camel_data_wrapper_decode_to_stream (dw, filtered_stream, NULL);
-			camel_stream_flush (filtered_stream, NULL);
+			camel_data_wrapper_decode_to_stream (dw, filtered_stream, NULL, NULL);
+			camel_stream_flush (filtered_stream, NULL, NULL);
 			g_object_unref (filtered_stream);
 
-			camel_stream_write (content, "", 1, NULL);
+			camel_stream_write (content, "", 1, NULL, NULL);
 			e_gw_item_set_message (item, (const gchar *)byte_array->data);
 		} else {
-			camel_data_wrapper_decode_to_stream (dw, content, NULL);
+			camel_data_wrapper_decode_to_stream (dw, content, NULL, NULL);
 			send_as_attachment (cnc, item, content, type, dw, NULL, NULL, &attach_list);
 		}
 
@@ -669,7 +668,7 @@ do_multipart (EGwConnection *cnc, EGwItem *item, CamelMultipart *mp, GSList **at
 			if (temp_part) {
 				is_alternative = TRUE;
 				temp_dw = camel_medium_get_content (CAMEL_MEDIUM (temp_part));
-				camel_data_wrapper_write_to_stream (temp_dw, temp_content, NULL);
+				camel_data_wrapper_write_to_stream (temp_dw, temp_content, NULL, NULL);
 				filename = camel_mime_part_get_filename (temp_part);
 				disposition = camel_mime_part_get_disposition (temp_part);
 				cid = camel_mime_part_get_content_id (temp_part);
@@ -700,18 +699,18 @@ do_multipart (EGwConnection *cnc, EGwItem *item, CamelMultipart *mp, GSList **at
 				filtered_stream = g_object_ref (content);
 			}
 
-			camel_data_wrapper_decode_to_stream (dw, filtered_stream, NULL);
-			camel_stream_flush (filtered_stream, NULL);
+			camel_data_wrapper_decode_to_stream (dw, filtered_stream, NULL, NULL);
+			camel_stream_flush (filtered_stream, NULL, NULL);
 			g_object_unref (filtered_stream);
 
-			camel_stream_write (content, "", 1, NULL);
+			camel_stream_write (content, "", 1, NULL, NULL);
 			e_gw_item_set_message (item, (const gchar *) buffer->data);
 		} else {
 			filename = camel_mime_part_get_filename (part);
 			disposition = camel_mime_part_get_disposition (part);
 			content_id = camel_mime_part_get_content_id (part);
 
-			camel_data_wrapper_decode_to_stream (dw, content, NULL);
+			camel_data_wrapper_decode_to_stream (dw, content, NULL, NULL);
 			send_as_attachment (cnc, item, content, type, dw, filename, content_id, attach_list);
 		}
 
diff --git a/camel/providers/imap/camel-imap-command.c b/camel/providers/imap/camel-imap-command.c
index 1f6c369..da91e7b 100644
--- a/camel/providers/imap/camel-imap-command.c
+++ b/camel/providers/imap/camel-imap-command.c
@@ -44,11 +44,13 @@
 extern gint camel_verbose_debug;
 
 static gboolean imap_command_start (CamelImapStore *store, CamelFolder *folder,
-				    const gchar *cmd, GError **error);
+				    const gchar *cmd, GCancellable *cancellable,
+				    GError **error);
 static CamelImapResponse *imap_read_response (CamelImapStore *store,
+					      GCancellable *cancellable,
 					      GError **error);
 static gchar *imap_read_untagged (CamelImapStore *store, gchar *line,
-				 GError **error);
+				 GCancellable *cancellable, GError **error);
 static gchar *imap_command_strdup_vprintf (CamelImapStore *store,
 					  const gchar *fmt, va_list ap);
 static gchar *imap_command_strdup_printf (CamelImapStore *store,
@@ -59,6 +61,7 @@ static gchar *imap_command_strdup_printf (CamelImapStore *store,
  * @store: the IMAP store
  * @folder: The folder to perform the operation in (or %NULL if not
  * relevant).
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  * @fmt: a sort of printf-style format string, followed by arguments
  *
@@ -84,6 +87,7 @@ static gchar *imap_command_strdup_printf (CamelImapStore *store,
 CamelImapResponse *
 camel_imap_command (CamelImapStore *store,
                     CamelFolder *folder,
+                    GCancellable *cancellable,
                     GError **error,
                     const gchar *fmt, ...)
 {
@@ -108,14 +112,14 @@ camel_imap_command (CamelImapStore *store,
 		cmd = imap_command_strdup_printf (store, "SELECT %F", full_name);
 	}
 
-	if (!imap_command_start (store, folder, cmd, error)) {
+	if (!imap_command_start (store, folder, cmd, cancellable, error)) {
 		g_free (cmd);
 		camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 		return NULL;
 	}
 	g_free (cmd);
 
-	return imap_read_response (store, error);
+	return imap_read_response (store, cancellable, error);
 }
 
 /**
@@ -123,6 +127,7 @@ camel_imap_command (CamelImapStore *store,
  * @store: the IMAP store
  * @folder: The folder to perform the operation in (or %NULL if not
  * relevant).
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  * @fmt: a sort of printf-style format string, followed by arguments
  *
@@ -155,6 +160,7 @@ camel_imap_command (CamelImapStore *store,
 gboolean
 camel_imap_command_start (CamelImapStore *store,
                           CamelFolder *folder,
+                          GCancellable *cancellable,
                           GError **error,
                           const gchar *fmt, ...)
 {
@@ -167,7 +173,7 @@ camel_imap_command_start (CamelImapStore *store,
 	va_end (ap);
 
 	camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-	ok = imap_command_start (store, folder, cmd, error);
+	ok = imap_command_start (store, folder, cmd, cancellable, error);
 	g_free (cmd);
 
 	if (!ok)
@@ -179,6 +185,7 @@ static gboolean
 imap_command_start (CamelImapStore *store,
                     CamelFolder *folder,
                     const gchar *cmd,
+                    GCancellable *cancellable,
                     GError **error)
 {
 	gssize nwritten;
@@ -204,11 +211,14 @@ imap_command_start (CamelImapStore *store,
 		CamelImapResponse *response;
 		GError *local_error = NULL;
 
-		response = camel_imap_command (store, folder, error, NULL);
+		response = camel_imap_command (
+			store, folder, cancellable, error, NULL);
 		if (!response)
 			return FALSE;
 
-		camel_imap_folder_selected (folder, response, &local_error);
+		/* FIXME Pass a GCancellable */
+		camel_imap_folder_selected (
+			folder, response, NULL, &local_error);
 		camel_imap_response_free (store, response);
 
 		if (local_error != NULL) {
@@ -276,6 +286,7 @@ CamelImapResponse *
 camel_imap_command_continuation (CamelImapStore *store,
                                  const gchar *cmd,
                                  gsize cmdlen,
+                                 GCancellable *cancellable,
                                  GError **error)
 {
 	if (!camel_imap_store_connected (store, error))
@@ -297,20 +308,21 @@ camel_imap_command_continuation (CamelImapStore *store,
 		return NULL;
 	}
 
-	if (camel_stream_write (store->ostream, cmd, cmdlen, error) == -1 ||
-	    camel_stream_write (store->ostream, "\r\n", 2, error) == -1) {
+	if (camel_stream_write (store->ostream, cmd, cmdlen, cancellable, error) == -1 ||
+	    camel_stream_write (store->ostream, "\r\n", 2, cancellable, error) == -1) {
 		camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
 		camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 		return NULL;
 	}
 
-	return imap_read_response (store, error);
+	return imap_read_response (store, cancellable, error);
 }
 
 /**
  * camel_imap_command_response:
  * @store: the IMAP store
  * @response: a pointer to pass back the response data in
+ * @cancellable: optional #GCancellable object, or %NULL
  * @error: return location for a #GError, or %NULL
  *
  * This reads a single tagged, untagged, or continuation response from
@@ -323,13 +335,15 @@ camel_imap_command_continuation (CamelImapStore *store,
  * command lock will be unlocked.
  **/
 CamelImapResponseType
-camel_imap_command_response (CamelImapStore *store, gchar **response,
-			     GError **error)
+camel_imap_command_response (CamelImapStore *store,
+                             gchar **response,
+                             GCancellable *cancellable,
+                             GError **error)
 {
 	CamelImapResponseType type;
 	gchar *respbuf;
 
-	if (camel_imap_store_readline (store, &respbuf, error) < 0) {
+	if (camel_imap_store_readline (store, &respbuf, cancellable, error) < 0) {
 		camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 		return CAMEL_IMAP_RESPONSE_ERROR;
 	}
@@ -360,7 +374,8 @@ camel_imap_command_response (CamelImapStore *store, gchar **response,
 
 		/* Read the rest of the response. */
 		type = CAMEL_IMAP_RESPONSE_UNTAGGED;
-		respbuf = imap_read_untagged (store, respbuf, error);
+		respbuf = imap_read_untagged (
+			store, respbuf, cancellable, error);
 		if (!respbuf)
 			type = CAMEL_IMAP_RESPONSE_ERROR;
 		else if (!g_ascii_strncasecmp (respbuf, "* OK [ALERT]", 12)
@@ -394,7 +409,9 @@ camel_imap_command_response (CamelImapStore *store, gchar **response,
 }
 
 static CamelImapResponse *
-imap_read_response (CamelImapStore *store, GError **error)
+imap_read_response (CamelImapStore *store,
+                    GCancellable *cancellable,
+                    GError **error)
 {
 	CamelImapResponse *response;
 	CamelImapResponseType type;
@@ -414,8 +431,9 @@ imap_read_response (CamelImapStore *store, GError **error)
 	} */
 
 	response->untagged = g_ptr_array_new ();
-	while ((type = camel_imap_command_response (store, &respbuf, error))
-	       == CAMEL_IMAP_RESPONSE_UNTAGGED)
+	while ((type = camel_imap_command_response (
+		store, &respbuf, cancellable, error))
+		== CAMEL_IMAP_RESPONSE_UNTAGGED)
 		g_ptr_array_add (response->untagged, respbuf);
 
 	if (type == CAMEL_IMAP_RESPONSE_ERROR) {
@@ -464,7 +482,10 @@ imap_read_response (CamelImapStore *store, GError **error)
  * of literals.
  */
 static gchar *
-imap_read_untagged (CamelImapStore *store, gchar *line, GError **error)
+imap_read_untagged (CamelImapStore *store,
+                    gchar *line,
+                    GCancellable *cancellable,
+                    GError **error)
 {
 	gint fulllen, ldigits, nread, n, i, sexp = 0;
 	guint length;
@@ -514,7 +535,8 @@ imap_read_untagged (CamelImapStore *store, gchar *line, GError **error)
 			n = camel_stream_read (
 				store->istream,
 				str->str + nread + 1,
-				length - nread, error);
+				length - nread,
+				cancellable, error);
 			if (n == -1) {
 				camel_service_disconnect (
 					CAMEL_SERVICE (store), FALSE, NULL);
@@ -583,7 +605,7 @@ imap_read_untagged (CamelImapStore *store, gchar *line, GError **error)
 
 		/* Read the next line. */
 		do {
-			if (camel_imap_store_readline (store, &line, error) < 0)
+			if (camel_imap_store_readline (store, &line, cancellable, error) < 0)
 				goto lose;
 
 			/* MAJOR HACK ALERT, gropuwise sometimes sends an extra blank line after literals, check that here
@@ -657,8 +679,10 @@ camel_imap_response_free (CamelImapStore *store, CamelImapResponse *response)
 	if (response->folder) {
 		if (exists > 0 || expunged) {
 			/* Update the summary */
-			camel_imap_folder_changed (response->folder,
-						   exists, expunged, NULL);
+			/* FIXME Pass a GCancellable */
+			camel_imap_folder_changed (
+				response->folder, exists,
+				expunged, NULL, NULL);
 			if (expunged)
 				g_array_free (expunged, TRUE);
 		}
diff --git a/camel/providers/imap/camel-imap-command.h b/camel/providers/imap/camel-imap-command.h
index 76b8f3d..4c82f5b 100644
--- a/camel/providers/imap/camel-imap-command.h
+++ b/camel/providers/imap/camel-imap-command.h
@@ -45,34 +45,41 @@ struct _CamelImapResponse {
 	gchar *status;
 };
 
-CamelImapResponse *camel_imap_command              (CamelImapStore *store,
-						    CamelFolder *folder,
-						    GError **error,
-						    const gchar *fmt, ...);
-CamelImapResponse *camel_imap_command_continuation (CamelImapStore *store,
-						    const gchar *cmd,
-						    gsize cmdlen,
-						    GError **error);
-
-void  camel_imap_response_free                     (CamelImapStore *store,
-						    CamelImapResponse *response);
-void  camel_imap_response_free_without_processing  (CamelImapStore *store,
-						    CamelImapResponse *response);
-gchar *camel_imap_response_extract                  (CamelImapStore *store,
-						    CamelImapResponse *response,
-						    const gchar *type,
-						    GError **error);
-gchar *camel_imap_response_extract_continuation     (CamelImapStore *store,
-						    CamelImapResponse *response,
-						    GError **error);
-
-gboolean           camel_imap_command_start        (CamelImapStore *store,
-						    CamelFolder *folder,
-						    GError **error,
-						    const gchar *fmt, ...);
-CamelImapResponseType camel_imap_command_response  (CamelImapStore *store,
-						    gchar **response,
-						    GError **error);
+CamelImapResponse *
+		camel_imap_command		(CamelImapStore *store,
+						 CamelFolder *folder,
+						 GCancellable *cancellable,
+						 GError **error,
+						 const gchar *fmt, ...);
+CamelImapResponse *
+		camel_imap_command_continuation	(CamelImapStore *store,
+						 const gchar *cmd,
+						 gsize cmdlen,
+						 GCancellable *cancellable,
+						 GError **error);
+void		camel_imap_response_free	(CamelImapStore *store,
+						 CamelImapResponse *response);
+void		camel_imap_response_free_without_processing
+						(CamelImapStore *store,
+						 CamelImapResponse *response);
+gchar *		camel_imap_response_extract	(CamelImapStore *store,
+						 CamelImapResponse *response,
+						 const gchar *type,
+						 GError **error);
+gchar *		camel_imap_response_extract_continuation
+						(CamelImapStore *store,
+						 CamelImapResponse *response,
+						 GError **error);
+gboolean	camel_imap_command_start	(CamelImapStore *store,
+						 CamelFolder *folder,
+						 GCancellable *cancellable,
+						 GError **error,
+						 const gchar *fmt, ...);
+CamelImapResponseType
+		camel_imap_command_response	(CamelImapStore *store,
+						 gchar **response,
+						 GCancellable *cancellable,
+						 GError **error);
 
 G_END_DECLS
 
diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c
index f16252a..d1b1ca2 100644
--- a/camel/providers/imap/camel-imap-folder.c
+++ b/camel/providers/imap/camel-imap-folder.c
@@ -71,25 +71,26 @@ enum {
 
 extern gint camel_application_is_exiting;
 
-static gboolean imap_rescan (CamelFolder *folder, gint exists, GError **error);
-static gboolean imap_refresh_info (CamelFolder *folder, GError **error);
+static gboolean imap_rescan (CamelFolder *folder, gint exists, GCancellable *cancellable, GError **error);
+static gboolean imap_refresh_info (CamelFolder *folder, GCancellable *cancellable, GError **error);
 static gboolean imap_sync_offline (CamelFolder *folder, GError **error);
-static gboolean imap_sync (CamelFolder *folder, gboolean expunge, GError **error);
-static gboolean imap_expunge_uids_online (CamelFolder *folder, GPtrArray *uids, GError **error);
-static gboolean imap_expunge_uids_offline (CamelFolder *folder, GPtrArray *uids, GError **error);
-static gboolean imap_expunge (CamelFolder *folder, GError **error);
+static gboolean imap_sync (CamelFolder *folder, gboolean expunge, GCancellable *cancellable, GError **error);
+static gboolean imap_expunge_uids_online (CamelFolder *folder, GPtrArray *uids, GCancellable *cancellable, GError **error);
+static gboolean imap_expunge_uids_offline (CamelFolder *folder, GPtrArray *uids, GCancellable *cancellable, GError **error);
+static gboolean imap_expunge (CamelFolder *folder, GCancellable *cancellable, GError **error);
 /*static void imap_cache_message (CamelDiscoFolder *disco_folder, const gchar *uid, GError **error);*/
 static void imap_rename (CamelFolder *folder, const gchar *new);
 static GPtrArray * imap_get_uncached_uids (CamelFolder *folder, GPtrArray * uids, GError **error);
 static gchar * imap_get_filename (CamelFolder *folder, const gchar *uid, GError **error);
 
 /* message manipulation */
-static CamelMimeMessage *imap_get_message (CamelFolder *folder, const gchar *uid,
+static CamelMimeMessage *imap_get_message (CamelFolder *folder, const gchar *uid, GCancellable *cancellable,
 					   GError **error);
-static gboolean imap_sync_message (CamelFolder *folder, const gchar *uid,
+static gboolean imap_sync_message (CamelFolder *folder, const gchar *uid, GCancellable *cancellable,
 			       GError **error);
 static gboolean imap_append_online (CamelFolder *folder, CamelMimeMessage *message,
 				const CamelMessageInfo *info, gchar **appended_uid,
+				GCancellable *cancellable,
 				GError **error);
 static gboolean imap_append_offline (CamelFolder *folder, CamelMimeMessage *message,
 				 const CamelMessageInfo *info, gchar **appended_uid,
@@ -98,10 +99,12 @@ static gboolean imap_append_offline (CamelFolder *folder, CamelMimeMessage *mess
 static gboolean imap_transfer_online (CamelFolder *source, GPtrArray *uids,
 				  CamelFolder *dest, GPtrArray **transferred_uids,
 				  gboolean delete_originals,
+				  GCancellable *cancellable,
 				  GError **error);
 static gboolean imap_transfer_offline (CamelFolder *source, GPtrArray *uids,
 				   CamelFolder *dest, GPtrArray **transferred_uids,
 				   gboolean delete_originals,
+				   GCancellable *cancellable,
 				   GError **error);
 
 /* searching */
@@ -125,7 +128,7 @@ static gboolean
 imap_transfer_messages (CamelFolder *source, GPtrArray *uids,
 			CamelFolder *dest, GPtrArray **transferred_uids,
 			gboolean delete_originals, gboolean can_call_sync,
-			GError **error);
+			GCancellable *cancellable, GError **error);
 
 #ifdef G_OS_WIN32
 /* The strtok() in Microsoft's C library is MT-safe (but still uses
@@ -308,7 +311,10 @@ camel_imap_folder_init (CamelImapFolder *imap_folder)
 }
 
 static void
-replay_offline_journal (CamelImapStore *imap_store, CamelImapFolder *imap_folder, GError **error)
+replay_offline_journal (CamelImapStore *imap_store,
+                        CamelImapFolder *imap_folder,
+                        GCancellable *cancellable,
+                        GError **error)
 {
 	CamelIMAPJournal *imap_journal;
 
@@ -327,7 +333,8 @@ replay_offline_journal (CamelImapStore *imap_store, CamelImapFolder *imap_folder
 	if (!imap_journal->rp_in_progress) {
 		imap_journal->rp_in_progress++;
 
-		camel_offline_journal_replay (imap_folder->journal, error);
+		camel_offline_journal_replay (
+			imap_folder->journal, cancellable, error);
 		camel_imap_journal_close_folders (imap_journal);
 		camel_offline_journal_write (imap_folder->journal, error);
 
@@ -414,9 +421,6 @@ camel_imap_folder_new (CamelStore *parent, const gchar *folder_name,
 
 	imap_folder->search = camel_imap_search_new (folder_dir);
 
-	/* do not do that here, as other folders for 'transfer' might not be opened yet
-	replay_offline_journal (imap_store, imap_folder, ex);*/
-
 	return folder;
 }
 
@@ -477,6 +481,7 @@ camel_imap_folder_set_check_folder (CamelImapFolder *imap_folder,
 gboolean
 camel_imap_folder_selected (CamelFolder *folder,
                             CamelImapResponse *response,
+                            GCancellable *cancellable,
                             GError **error)
 {
 	CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
@@ -532,7 +537,8 @@ camel_imap_folder_selected (CamelFolder *folder,
 		camel_imap_message_cache_clear (imap_folder->cache);
 		CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
 		imap_folder->need_rescan = FALSE;
-		return camel_imap_folder_changed (folder, exists, NULL, error);
+		return camel_imap_folder_changed (
+			folder, exists, NULL, cancellable, error);
 	}
 
 	/* If we've lost messages, we have to rescan everything */
@@ -553,7 +559,7 @@ camel_imap_folder_selected (CamelFolder *folder,
 		 * is selected, and we don't want camel_imap_command
 		 * to worry about it.)
 		 */
-		response = camel_imap_command (store, NULL, error, "FETCH %d UID", count);
+		response = camel_imap_command (store, NULL, cancellable, error, "FETCH %d UID", count);
 		if (!response)
 			return FALSE;
 		uid = 0;
@@ -587,13 +593,14 @@ camel_imap_folder_selected (CamelFolder *folder,
 
 	/* Now rescan if we need to */
 	if (imap_folder->need_rescan)
-		return imap_rescan (folder, exists, error);
+		return imap_rescan (folder, exists, cancellable, error);
 
 	/* If we don't need to rescan completely, but new messages
 	 * have been added, find out about them.
 	 */
 	if (exists > count)
-		camel_imap_folder_changed (folder, exists, NULL, error);
+		camel_imap_folder_changed (
+			folder, exists, NULL, cancellable, error);
 
 	/* And we're done. */
 
@@ -645,7 +652,11 @@ imap_rename (CamelFolder *folder, const gchar *new)
 
 /* called with connect_lock locked */
 static gboolean
-get_folder_status (CamelFolder *folder, guint32 *total, guint32 *unread, GError **error)
+get_folder_status (CamelFolder *folder,
+                   guint32 *total,
+                   guint32 *unread,
+                   GCancellable *cancellable,
+                   GError **error)
 {
 	CamelStore *parent_store;
 	CamelImapStore *imap_store;
@@ -660,7 +671,7 @@ get_folder_status (CamelFolder *folder, guint32 *total, guint32 *unread, GError
 
 	imap_store = CAMEL_IMAP_STORE (parent_store);
 
-	response = camel_imap_command (imap_store, folder, error, "STATUS %F (MESSAGES UNSEEN)", full_name);
+	response = camel_imap_command (imap_store, folder, cancellable, error, "STATUS %F (MESSAGES UNSEEN)", full_name);
 
 	if (response) {
 		gint i;
@@ -724,6 +735,7 @@ get_folder_status (CamelFolder *folder, guint32 *total, guint32 *unread, GError
 
 static gboolean
 imap_refresh_info (CamelFolder *folder,
+                   GCancellable *cancellable,
                    GError **error)
 {
 	CamelStore *parent_store;
@@ -757,15 +769,18 @@ imap_refresh_info (CamelFolder *folder,
 		goto done;
 
 	/* try to store local changes first, as the summary contains new local messages */
-	replay_offline_journal (imap_store, imap_folder, &local_error);
+	replay_offline_journal (
+		imap_store, imap_folder, cancellable, &local_error);
 
 	full_name = camel_folder_get_full_name (folder);
 
 	if (imap_store->current_folder != folder
 	    || g_ascii_strcasecmp (full_name, "INBOX") == 0) {
-		response = camel_imap_command (imap_store, folder, &local_error, NULL);
+		response = camel_imap_command (imap_store, folder, cancellable, &local_error, NULL);
 		if (response) {
-			camel_imap_folder_selected (folder, response, &local_error);
+			camel_imap_folder_selected (
+				folder, response,
+				cancellable, &local_error);
 			camel_imap_response_free (imap_store, response);
 		}
 	} else if (imap_folder->need_rescan) {
@@ -773,7 +788,9 @@ imap_refresh_info (CamelFolder *folder,
 		 * a NOOP to give the server a chance to tell us about new
 		 * messages.
 		 */
-		imap_rescan (folder, camel_folder_summary_count (folder->summary), &local_error);
+		imap_rescan (
+			folder, camel_folder_summary_count (
+			folder->summary), cancellable, &local_error);
 		check_rescan = 0;
 	} else {
 #if 0
@@ -784,7 +801,7 @@ imap_refresh_info (CamelFolder *folder,
 			camel_imap_response_free (imap_store, response);
 		}
 #endif
-		response = camel_imap_command (imap_store, folder, &local_error, "NOOP");
+		response = camel_imap_command (imap_store, folder, cancellable, &local_error, "NOOP");
 		camel_imap_response_free (imap_store, response);
 	}
 
@@ -813,7 +830,7 @@ imap_refresh_info (CamelFolder *folder,
 
 			/* Check whether there are changes in total/unread messages in the folders
 			   and if so, then rescan whole summary */
-			if (get_folder_status (folder, &server_total, &server_unread, &local_error)) {
+			if (get_folder_status (folder, &server_total, &server_unread, cancellable, &local_error)) {
 
 				total = camel_folder_summary_count (folder->summary);
 				unread = folder->summary->unread_count;
@@ -824,7 +841,9 @@ imap_refresh_info (CamelFolder *folder,
 		}
 
 		if (check_rescan)
-			imap_rescan (folder, camel_folder_summary_count (folder->summary), &local_error);
+			imap_rescan (
+				folder, camel_folder_summary_count (
+				folder->summary), cancellable, &local_error);
 	}
 done:
 	camel_service_unlock (CAMEL_SERVICE (imap_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
@@ -919,7 +938,10 @@ merge_custom_flags (CamelMessageInfo *mi, const gchar *custom_flags)
 
 /* Called with the store's connect_lock locked */
 static gboolean
-imap_rescan (CamelFolder *folder, gint exists, GError **error)
+imap_rescan (CamelFolder *folder,
+             gint exists,
+             GCancellable *cancellable,
+             GError **error)
 {
 	CamelStore *parent_store;
 	CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
@@ -951,33 +973,34 @@ imap_rescan (CamelFolder *folder, gint exists, GError **error)
 	summary_len = camel_folder_summary_count (folder->summary);
 	if (summary_len == 0) {
 		if (exists)
-			return camel_imap_folder_changed (folder, exists, NULL, error);
+			return camel_imap_folder_changed (
+				folder, exists, NULL, cancellable, error);
 		return TRUE;
 	}
 
 	/* Check UIDs and flags of all messages we already know of. */
 	camel_operation_start (
-		NULL, _("Scanning for changed messages in %s"),
+		cancellable, _("Scanning for changed messages in %s"),
 		camel_folder_get_name (folder));
 	uid = camel_folder_summary_uid_from_index (folder->summary, summary_len - 1);
 
 	if (!uid) {
-		camel_operation_end (NULL);
+		camel_operation_end (cancellable);
 		return TRUE;
 	}
 
 	ok = camel_imap_command_start (
-		store, folder, error,
+		store, folder, cancellable, error,
 		"UID FETCH 1:%s (FLAGS)", uid);
 	g_free (uid);
 	if (!ok) {
-		camel_operation_end (NULL);
+		camel_operation_end (cancellable);
 		return FALSE;
 	}
 
 	new = g_malloc0 (summary_len * sizeof (*new));
 	summary_got = 0;
-	while ((type = camel_imap_command_response (store, &resp, error)) == CAMEL_IMAP_RESPONSE_UNTAGGED && !camel_application_is_exiting) {
+	while ((type = camel_imap_command_response (store, &resp, cancellable, error)) == CAMEL_IMAP_RESPONSE_UNTAGGED && !camel_application_is_exiting) {
 		GData *data;
 		gchar *uid;
 		guint32 flags;
@@ -996,7 +1019,9 @@ imap_rescan (CamelFolder *folder, gint exists, GError **error)
 			continue;
 		}
 
-		camel_operation_progress (NULL, ++summary_got * 100 / summary_len);
+		camel_operation_progress (
+			cancellable, ++summary_got * 100 / summary_len);
+
 		new[seq - 1].uid = g_strdup (uid);
 		new[seq - 1].flags = flags;
 		new[seq - 1].custom_flags = g_strdup (g_datalist_get_data (&data, "CUSTOM.FLAGS"));
@@ -1004,12 +1029,14 @@ imap_rescan (CamelFolder *folder, gint exists, GError **error)
 	}
 
 	if (summary_got == 0 && summary_len == 0) {
-		camel_operation_end (NULL);
+		camel_operation_end (cancellable);
 		camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 		g_free (new);
 		return TRUE;
 	}
-	camel_operation_end (NULL);
+
+	camel_operation_end (cancellable);
+
 	if (type == CAMEL_IMAP_RESPONSE_ERROR || camel_application_is_exiting) {
 		for (i = 0; i < summary_len && new[i].uid; i++) {
 			g_free (new[i].uid);
@@ -1231,7 +1258,8 @@ imap_rescan (CamelFolder *folder, gint exists, GError **error)
 	}
 
 	/* And finally update the summary. */
-	success = camel_imap_folder_changed (folder, exists, removed, error);
+	success = camel_imap_folder_changed (
+		folder, exists, removed, cancellable, error);
 	g_array_free (removed, TRUE);
 
 	return success;
@@ -1445,6 +1473,7 @@ static void
 move_messages (CamelFolder *src_folder,
                GPtrArray *uids,
                CamelFolder *des_folder,
+               GCancellable *cancellable,
                GError **error)
 {
 	g_return_if_fail (src_folder != NULL);
@@ -1456,16 +1485,19 @@ move_messages (CamelFolder *src_folder,
 	/* moving to the same folder means expunge only */
 	if (src_folder != des_folder) {
 		/* do 'copy' to not be bothered with CAMEL_MESSAGE_DELETED again */
-		if (!imap_transfer_messages (src_folder, uids, des_folder, NULL, FALSE, FALSE, error))
+		if (!imap_transfer_messages (
+			src_folder, uids, des_folder, NULL,
+			FALSE, FALSE, cancellable, error))
 			return;
 	}
 
-	camel_imap_expunge_uids_only (src_folder, uids, error);
+	camel_imap_expunge_uids_only (src_folder, uids, cancellable, error);
 }
 
 static gboolean
 imap_sync (CamelFolder *folder,
            gboolean expunge,
+           GCancellable *cancellable,
            GError **error)
 {
 	CamelStore *parent_store;
@@ -1486,7 +1518,7 @@ imap_sync (CamelFolder *folder,
 
 	if (folder->permanent_flags == 0 || CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
 		if (expunge) {
-			if (!imap_expunge (folder, error))
+			if (!imap_expunge (folder, cancellable, error))
 				return FALSE;
 		}
 		return imap_sync_offline (folder, error);
@@ -1495,7 +1527,7 @@ imap_sync (CamelFolder *folder,
 	camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
 	/* write local changes first */
-	replay_offline_journal (store, imap_folder, NULL);
+	replay_offline_journal (store, imap_folder, cancellable, NULL);
 
 	/* Find a message with changed flags, find all of the other
 	 * messages like it, sync them as a group, mark them as
@@ -1512,7 +1544,8 @@ imap_sync (CamelFolder *folder,
 			real_trash = folder;
 			g_object_ref (real_trash);
 		} else {
-			real_trash = camel_store_get_trash (parent_store, NULL);
+			real_trash = camel_store_get_trash (
+				parent_store, cancellable, NULL);
 
 			if (!store->real_trash_path && real_trash) {
 				/* failed to open real trash */
@@ -1531,7 +1564,8 @@ imap_sync (CamelFolder *folder,
 			/* syncing the junk, but cannot move messages to itself, thus do nothing */
 			real_junk = NULL;
 		} else {
-			real_junk = camel_store_get_junk (parent_store, NULL);
+			real_junk = camel_store_get_junk (
+				parent_store, cancellable, NULL);
 
 			if (!store->real_junk_path && real_junk) {
 				/* failed to open real junk */
@@ -1605,7 +1639,7 @@ imap_sync (CamelFolder *folder,
 				g_free (flaglist);
 				flaglist = strdup ("(\\Seen)");
 
-				response = camel_imap_command (store, folder, &local_error,
+				response = camel_imap_command (store, folder, cancellable, &local_error,
 						"UID STORE %s +FLAGS.SILENT %s",
 						set, flaglist);
 				if (response)
@@ -1620,7 +1654,7 @@ imap_sync (CamelFolder *folder,
 
 		/* Note: to 'unset' flags, use -FLAGS.SILENT (<flag list>) */
 		if (local_error == NULL) {
-			response = camel_imap_command (store, folder, &local_error,
+			response = camel_imap_command (store, folder, cancellable, &local_error,
 					       "UID STORE %s %sFLAGS.SILENT %s",
 					       set, unset ? "-" : "", flaglist);
 		}
@@ -1680,9 +1714,13 @@ imap_sync (CamelFolder *folder,
 	}
 
 	if (local_error == NULL)
-		move_messages (folder, deleted_uids, real_trash, &local_error);
+		move_messages (
+			folder, deleted_uids, real_trash,
+			cancellable, &local_error);
 	if (local_error == NULL)
-		move_messages (folder, junked_uids, real_junk, &local_error);
+		move_messages (
+			folder, junked_uids, real_junk,
+			cancellable, &local_error);
 
 	if (deleted_uids) {
 		g_ptr_array_foreach (deleted_uids, (GFunc) camel_pstring_free, NULL);
@@ -1698,7 +1736,7 @@ imap_sync (CamelFolder *folder,
 		g_object_unref (real_junk);
 
 	if (expunge && local_error == NULL)
-		imap_expunge (folder, &local_error);
+		imap_expunge (folder, cancellable, &local_error);
 
 	if (local_error != NULL)
 		g_propagate_error (error, local_error);
@@ -1733,6 +1771,7 @@ uid_compar (gconstpointer va, gconstpointer vb)
 static gboolean
 imap_expunge_uids_offline (CamelFolder *folder,
                            GPtrArray *uids,
+                           GCancellable *cancellable,
                            GError **error)
 {
 	CamelFolderChangeInfo *changes;
@@ -1773,6 +1812,7 @@ imap_expunge_uids_offline (CamelFolder *folder,
 static gboolean
 imap_expunge_uids_online (CamelFolder *folder,
                           GPtrArray *uids,
+                          GCancellable *cancellable,
                           GError **error)
 {
 	CamelImapStore *store;
@@ -1795,7 +1835,7 @@ imap_expunge_uids_online (CamelFolder *folder,
 	camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
 	if ((store->capabilities & IMAP_CAPABILITY_UIDPLUS) == 0) {
-		if (!CAMEL_FOLDER_GET_CLASS (folder)->sync (folder, 0, error)) {
+		if (!CAMEL_FOLDER_GET_CLASS (folder)->sync (folder, 0, cancellable, error)) {
 			camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 			return FALSE;
 		}
@@ -1805,7 +1845,7 @@ imap_expunge_uids_online (CamelFolder *folder,
 
 	while (uid < uids->len) {
 		set = imap_uid_array_to_set (folder->summary, uids, uid, UID_SET_LIMIT, &uid);
-		response = camel_imap_command (store, folder, error,
+		response = camel_imap_command (store, folder, cancellable, error,
 					       "UID STORE %s +FLAGS.SILENT (\\Deleted)",
 					       set);
 		if (response)
@@ -1820,7 +1860,7 @@ imap_expunge_uids_online (CamelFolder *folder,
 			GError *local_error = NULL;
 
 			response = camel_imap_command (
-				store, folder, &local_error,
+				store, folder, cancellable, &local_error,
 				"UID EXPUNGE %s", set);
 
 			if (local_error != NULL) {
@@ -1836,7 +1876,7 @@ imap_expunge_uids_online (CamelFolder *folder,
 		}
 
 		if (full_expunge)
-			response = camel_imap_command (store, folder, NULL, "EXPUNGE");
+			response = camel_imap_command (store, folder, cancellable, NULL, "EXPUNGE");
 
 		if (response)
 			camel_imap_response_free (store, response);
@@ -1867,6 +1907,7 @@ imap_expunge_uids_online (CamelFolder *folder,
 
 static gboolean
 imap_expunge (CamelFolder *folder,
+              GCancellable *cancellable,
               GError **error)
 {
 	CamelStore *parent_store;
@@ -1883,7 +1924,8 @@ imap_expunge (CamelFolder *folder,
 		CamelFolder *trash;
 		GError *local_error = NULL;
 
-		trash = camel_store_get_trash (parent_store, &local_error);
+		trash = camel_store_get_trash (
+			parent_store, cancellable, &local_error);
 
 		if (local_error == NULL && trash && (folder == trash || g_ascii_strcasecmp (full_name, camel_folder_get_full_name (trash)) == 0)) {
 			/* it's a real trash folder, thus get all mails from there */
@@ -1901,9 +1943,11 @@ imap_expunge (CamelFolder *folder,
 		return TRUE;
 
 	if (CAMEL_OFFLINE_STORE (parent_store)->state == CAMEL_OFFLINE_STORE_NETWORK_AVAIL)
-		success = imap_expunge_uids_online (folder, uids, error);
+		success = imap_expunge_uids_online (
+			folder, uids, cancellable, error);
 	else
-		success = imap_expunge_uids_offline (folder, uids, error);
+		success = imap_expunge_uids_offline (
+			folder, uids, cancellable, error);
 
 	g_ptr_array_foreach (uids, (GFunc) camel_pstring_free, NULL);
 	g_ptr_array_free (uids, TRUE);
@@ -1914,6 +1958,7 @@ imap_expunge (CamelFolder *folder,
 gboolean
 camel_imap_expunge_uids_resyncing (CamelFolder *folder,
                                    GPtrArray *uids,
+                                   GCancellable *cancellable,
                                    GError **error)
 {
 	CamelStore *parent_store;
@@ -1930,7 +1975,8 @@ camel_imap_expunge_uids_resyncing (CamelFolder *folder,
 		return TRUE;
 
 	if (store->capabilities & IMAP_CAPABILITY_UIDPLUS)
-		return imap_expunge_uids_online (folder, uids, error);
+		return imap_expunge_uids_online (
+			folder, uids, cancellable, error);
 
 	/* If we don't have UID EXPUNGE we need to avoid expunging any
 	 * of the wrong messages. So we search for deleted messages,
@@ -1940,12 +1986,12 @@ camel_imap_expunge_uids_resyncing (CamelFolder *folder,
 
 	camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
-	if (!CAMEL_FOLDER_GET_CLASS (folder)->sync (folder, 0, error)) {
+	if (!CAMEL_FOLDER_GET_CLASS (folder)->sync (folder, 0, cancellable, error)) {
 		camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 		return FALSE;
 	}
 
-	response = camel_imap_command (store, folder, error, "UID SEARCH DELETED");
+	response = camel_imap_command (store, folder, cancellable, error, "UID SEARCH DELETED");
 	if (!response) {
 		camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 		return FALSE;
@@ -2004,7 +2050,7 @@ camel_imap_expunge_uids_resyncing (CamelFolder *folder,
 		while (uid < keep_uids->len) {
 			uidset = imap_uid_array_to_set (folder->summary, keep_uids, uid, UID_SET_LIMIT, &uid);
 
-			response = camel_imap_command (store, folder, error,
+			response = camel_imap_command (store, folder, cancellable, error,
 						       "UID STORE %s -FLAGS.SILENT (\\Deleted)",
 						       uidset);
 
@@ -2028,7 +2074,7 @@ camel_imap_expunge_uids_resyncing (CamelFolder *folder,
 		while (uid < mark_uids->len) {
 			uidset = imap_uid_array_to_set (folder->summary, mark_uids, uid, UID_SET_LIMIT, &uid);
 
-			response = camel_imap_command (store, folder, error,
+			response = camel_imap_command (store, folder, cancellable, error,
 						       "UID STORE %s +FLAGS.SILENT (\\Deleted)",
 						       uidset);
 
@@ -2048,7 +2094,7 @@ camel_imap_expunge_uids_resyncing (CamelFolder *folder,
 	}
 
 	/* Do the actual expunging */
-	response = camel_imap_command (store, folder, NULL, "EXPUNGE");
+	response = camel_imap_command (store, folder, cancellable, NULL, "EXPUNGE");
 	if (response)
 		camel_imap_response_free (store, response);
 
@@ -2060,7 +2106,7 @@ camel_imap_expunge_uids_resyncing (CamelFolder *folder,
 		while (uid < keep_uids->len) {
 			uidset = imap_uid_array_to_set (folder->summary, keep_uids, uid, UID_SET_LIMIT, &uid);
 
-			response = camel_imap_command (store, folder, NULL,
+			response = camel_imap_command (store, folder, cancellable, NULL,
 						       "UID STORE %s +FLAGS.SILENT (\\Deleted)",
 						       uidset);
 
@@ -2083,6 +2129,7 @@ camel_imap_expunge_uids_resyncing (CamelFolder *folder,
 gboolean
 camel_imap_expunge_uids_only (CamelFolder *folder,
                               GPtrArray *uids,
+                              GCancellable *cancellable,
                               GError **error)
 {
 	CamelStore *parent_store;
@@ -2095,9 +2142,11 @@ camel_imap_expunge_uids_only (CamelFolder *folder,
 	g_return_val_if_fail (uids != NULL, FALSE);
 
 	if (CAMEL_OFFLINE_STORE (parent_store)->state == CAMEL_OFFLINE_STORE_NETWORK_AVAIL)
-		return camel_imap_expunge_uids_resyncing (folder, uids, error);
+		return camel_imap_expunge_uids_resyncing (
+			folder, uids, cancellable, error);
 	else
-		return imap_expunge_uids_offline (folder, uids, error);
+		return imap_expunge_uids_offline (
+			folder, uids, cancellable, error);
 }
 
 static gchar *
@@ -2130,7 +2179,8 @@ imap_append_offline (CamelFolder *folder,
 
 	uid = get_temp_uid ();
 
-	camel_imap_summary_add_offline (folder->summary, uid, message, info);
+	camel_imap_summary_add_offline (
+		folder->summary, uid, message, info);
 	CAMEL_IMAP_FOLDER_REC_LOCK (folder, cache_lock);
 	camel_imap_message_cache_insert_wrapper (
 		cache, uid, "", CAMEL_DATA_WRAPPER (message));
@@ -2177,6 +2227,7 @@ do_append (CamelFolder *folder,
            CamelMimeMessage *message,
            const CamelMessageInfo *info,
            gchar **uid,
+           GCancellable *cancellable,
            GError **error)
 {
 	CamelStore *parent_store;
@@ -2209,7 +2260,7 @@ do_append (CamelFolder *folder,
 	camel_stream_filter_add (
 		CAMEL_STREAM_FILTER (streamfilter), crlf_filter);
 	camel_data_wrapper_write_to_stream (
-		CAMEL_DATA_WRAPPER (message), streamfilter, NULL);
+		CAMEL_DATA_WRAPPER (message), streamfilter, cancellable, NULL);
 	g_object_unref (streamfilter);
 	g_object_unref (crlf_filter);
 	g_object_unref (memstream);
@@ -2229,7 +2280,7 @@ retry:
 
 	full_name = camel_folder_get_full_name (folder);
 	response = camel_imap_command (
-		store, NULL, &local_error, "APPEND %F%s%s {%d}",
+		store, NULL, cancellable, &local_error, "APPEND %F%s%s {%d}",
 		full_name, flagstr ? " " : "",
 		flagstr ? flagstr : "", ba->len);
 	g_free (flagstr);
@@ -2252,7 +2303,7 @@ retry:
 	}
 
 	/* send the rest of our data - the mime message */
-	response2 = camel_imap_command_continuation (store, (const gchar *) ba->data, ba->len, error);
+	response2 = camel_imap_command_continuation (store, (const gchar *) ba->data, ba->len, cancellable, error);
 	g_byte_array_free (ba, TRUE);
 
 	/* free it only after message is sent. This may cause more FETCHes. */
@@ -2286,6 +2337,7 @@ imap_append_online (CamelFolder *folder,
                     CamelMimeMessage *message,
                     const CamelMessageInfo *info,
                     gchar **appended_uid,
+                    GCancellable *cancellable,
                     GError **error)
 {
 	CamelStore *parent_store;
@@ -2299,11 +2351,12 @@ imap_append_online (CamelFolder *folder,
 	store = CAMEL_IMAP_STORE (parent_store);
 
 	if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
-		return imap_append_offline (folder, message, info, appended_uid, error);
+		return imap_append_offline (
+			folder, message, info, appended_uid, error);
 	}
 
 	count = camel_folder_summary_count (folder->summary);
-	response = do_append (folder, message, info, &uid, error);
+	response = do_append (folder, message, info, &uid, cancellable, error);
 	if (!response)
 		return FALSE;
 
@@ -2329,7 +2382,7 @@ imap_append_online (CamelFolder *folder,
 	camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 	if (store->current_folder != folder ||
 	    camel_folder_summary_count (folder->summary) == count)
-		success = imap_refresh_info (folder, error);
+		success = imap_refresh_info (folder, cancellable, error);
 	camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
 	return success;
@@ -2340,6 +2393,7 @@ camel_imap_append_resyncing (CamelFolder *folder,
                              CamelMimeMessage *message,
                              const CamelMessageInfo *info,
                              gchar **appended_uid,
+                             GCancellable *cancellable,
                              GError **error)
 {
 	CamelStore *parent_store;
@@ -2350,7 +2404,7 @@ camel_imap_append_resyncing (CamelFolder *folder,
 	parent_store = camel_folder_get_parent_store (folder);
 	store = CAMEL_IMAP_STORE (parent_store);
 
-	response = do_append (folder, message, info, &uid, error);
+	response = do_append (folder, message, info, &uid, cancellable, error);
 	if (!response)
 		return FALSE;
 
@@ -2381,6 +2435,7 @@ imap_transfer_offline (CamelFolder *source,
                        CamelFolder *dest,
                        GPtrArray **transferred_uids,
                        gboolean delete_originals,
+                       GCancellable *cancellable,
                        GError **error)
 {
 	CamelStore *parent_store;
@@ -2422,13 +2477,16 @@ imap_transfer_offline (CamelFolder *source,
 		mi = camel_folder_summary_uid (source->summary, uid);
 		g_return_val_if_fail (mi != NULL, FALSE);
 
-		message = camel_folder_get_message (source, uid, NULL);
+		message = camel_folder_get_message (
+			source, uid, cancellable, NULL);
 
 		if (message) {
-			camel_imap_summary_add_offline (dest->summary, destuid, message, mi);
+			camel_imap_summary_add_offline (
+				dest->summary, destuid, message, mi);
 			g_object_unref (CAMEL_OBJECT (message));
 		} else
-			camel_imap_summary_add_offline_uncached (dest->summary, destuid, mi);
+			camel_imap_summary_add_offline_uncached (
+				dest->summary, destuid, mi);
 
 		camel_imap_message_cache_copy (sc, uid, dc, destuid);
 		camel_message_info_free (mi);
@@ -2522,7 +2580,8 @@ handle_copyuid (CamelImapResponse *response, CamelFolder *source,
 static void
 handle_copyuid_copy_user_tags (CamelImapResponse *response,
                                CamelFolder *source,
-                               CamelFolder *destination)
+                               CamelFolder *destination,
+                               GCancellable *cancellable)
 {
 	CamelStore *parent_store;
 	gchar *validity, *srcset, *destset;
@@ -2548,11 +2607,11 @@ handle_copyuid_copy_user_tags (CamelImapResponse *response,
 	parent_store = camel_folder_get_parent_store (destination);
 	camel_imap_response_free (
 		CAMEL_IMAP_STORE (parent_store), camel_imap_command (
-		CAMEL_IMAP_STORE (parent_store), destination, NULL, "NOOP"));
+		CAMEL_IMAP_STORE (parent_store), destination, cancellable, NULL, "NOOP"));
 
 	/* refresh folder's summary first, we copied messages there on the server,
 	   but do not know about it in a local summary */
-	if (!imap_refresh_info (destination, NULL))
+	if (!imap_refresh_info (destination, cancellable, NULL))
 		goto lose;
 
 	src = imap_uid_set_to_array (source->summary, srcset);
@@ -2633,6 +2692,7 @@ do_copy (CamelFolder *source,
          GPtrArray *uids,
          CamelFolder *destination,
          gint delete_originals,
+         GCancellable *cancellable,
          GError **error)
 {
 	CamelStore *parent_store;
@@ -2654,26 +2714,27 @@ do_copy (CamelFolder *source,
 		/* use XGWMOVE only when none of the moving messages has set any user tag */
 		if ((store->capabilities & IMAP_CAPABILITY_XGWMOVE) != 0 && delete_originals && !any_has_user_tag (source, uidset)) {
 			response = camel_imap_command (
-				store, source, &local_error,
-				"UID XGWMOVE %s %F", uidset,
-				full_name);
+				store, source, cancellable, &local_error,
+				"UID XGWMOVE %s %F", uidset, full_name);
 			/* returns only 'A00012 OK UID XGWMOVE completed' '* 2 XGWMOVE' so nothing useful */
 			camel_imap_response_free (store, response);
 		} else {
 			response = camel_imap_command (
-				store, source, &local_error,
-				"UID COPY %s %F", uidset,
-				full_name);
+				store, source, cancellable, &local_error,
+				"UID COPY %s %F", uidset, full_name);
 			if (response && (store->capabilities & IMAP_CAPABILITY_UIDPLUS))
 				handle_copyuid (response, source, destination);
 			if (response)
-				handle_copyuid_copy_user_tags (response, source, destination);
+				handle_copyuid_copy_user_tags (
+					response, source, destination,
+					cancellable);
 			camel_imap_response_free (store, response);
 		}
 
 		if (local_error == NULL && delete_originals) {
 			for (i=last;i<uid;i++)
-				camel_folder_delete_message (source, uids->pdata[i]);
+				camel_folder_delete_message (
+					source, uids->pdata[i]);
 			last = uid;
 		}
 		g_free (uidset);
@@ -2694,6 +2755,7 @@ imap_transfer_messages (CamelFolder *source,
                         GPtrArray **transferred_uids,
                         gboolean delete_originals,
                         gboolean can_call_sync,
+                        GCancellable *cancellable,
                         GError **error)
 {
 	CamelStore *parent_store;
@@ -2707,10 +2769,10 @@ imap_transfer_messages (CamelFolder *source,
 	if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
 		return imap_transfer_offline (
 			source, uids, dest, transferred_uids,
-			delete_originals, error);
+			delete_originals, cancellable, error);
 
 	/* Sync message flags if needed. */
-	if (can_call_sync && !imap_sync (source, FALSE, error))
+	if (can_call_sync && !imap_sync (source, FALSE, cancellable, error))
 		return FALSE;
 
 	count = camel_folder_summary_count (dest->summary);
@@ -2718,13 +2780,13 @@ imap_transfer_messages (CamelFolder *source,
 	qsort (uids->pdata, uids->len, sizeof (gpointer), uid_compar);
 
 	/* Now copy the messages */
-	if (!do_copy (source, uids, dest, delete_originals, error))
+	if (!do_copy (source, uids, dest, delete_originals, cancellable, error))
 		return FALSE;
 
 	/* Make the destination notice its new messages */
 	if (store->current_folder != dest ||
 	    camel_folder_summary_count (dest->summary) == count)
-		success = imap_refresh_info (dest, error);
+		success = imap_refresh_info (dest, cancellable, error);
 
 	/* FIXME */
 	if (transferred_uids)
@@ -2739,9 +2801,12 @@ imap_transfer_online (CamelFolder *source,
                       CamelFolder *dest,
                       GPtrArray **transferred_uids,
                       gboolean delete_originals,
+                      GCancellable *cancellable,
                       GError **error)
 {
-	return imap_transfer_messages (source, uids, dest, transferred_uids, delete_originals, TRUE, error);
+	return imap_transfer_messages (
+		source, uids, dest, transferred_uids,
+		delete_originals, TRUE, cancellable, error);
 }
 
 gboolean
@@ -2750,6 +2815,7 @@ camel_imap_transfer_resyncing (CamelFolder *source,
                                CamelFolder *dest,
                                GPtrArray **transferred_uids,
                                gboolean delete_originals,
+                               GCancellable *cancellable,
                                GError **error)
 {
 	GPtrArray *realuids;
@@ -2785,7 +2851,9 @@ camel_imap_transfer_resyncing (CamelFolder *source,
 
 		/* If we saw any real UIDs, do a COPY */
 		if (i != first) {
-			do_copy (source, realuids, dest, delete_originals, &local_error);
+			do_copy (
+				source, realuids, dest, delete_originals,
+				cancellable, &local_error);
 			g_ptr_array_set_size (realuids, 0);
 			if (i == uids->len || local_error != NULL)
 				break;
@@ -2796,7 +2864,8 @@ camel_imap_transfer_resyncing (CamelFolder *source,
 		       !isdigit (*(guchar *)(uids->pdata[i])) &&
 		       local_error == NULL) {
 			uid = uids->pdata[i];
-			message = camel_folder_get_message (source, uid, NULL);
+			message = camel_folder_get_message (
+				source, uid, cancellable, NULL);
 			if (!message) {
 				/* Message must have been expunged */
 				i++;
@@ -2805,7 +2874,9 @@ camel_imap_transfer_resyncing (CamelFolder *source,
 			info = camel_folder_get_message_info (source, uid);
 			g_return_val_if_fail (info != NULL, FALSE);
 
-			imap_append_online (dest, message, info, NULL, &local_error);
+			imap_append_online (
+				dest, message, info,
+				NULL, cancellable, &local_error);
 			camel_folder_free_message_info (source, info);
 			g_object_unref (CAMEL_OBJECT (message));
 			if (delete_originals && local_error == NULL)
@@ -2909,6 +2980,7 @@ imap_search_free (CamelFolder *folder, GPtrArray *uids)
 static CamelMimeMessage *get_message (CamelImapFolder *imap_folder,
 				      const gchar *uid,
 				      CamelMessageContentInfo *ci,
+				      GCancellable *cancellable,
 				      GError **error);
 
 struct _part_spec_stack {
@@ -2998,10 +3070,13 @@ content_info_get_part_spec (CamelMessageContentInfo *ci)
  * of message @uid in @folder.
  */
 static CamelDataWrapper *
-get_content (CamelImapFolder *imap_folder, const gchar *uid,
-	     CamelMimePart *part, CamelMessageContentInfo *ci,
-	     gint frommsg,
-	     GError **error)
+get_content (CamelImapFolder *imap_folder,
+             const gchar *uid,
+             CamelMimePart *part,
+             CamelMessageContentInfo *ci,
+             gint frommsg,
+             GCancellable *cancellable,
+             GError **error)
 {
 	CamelDataWrapper *content = NULL;
 	CamelStream *stream;
@@ -3032,10 +3107,10 @@ get_content (CamelImapFolder *imap_folder, const gchar *uid,
 			strcpy (spec, part_spec);
 		g_free (part_spec);
 
-		stream = camel_imap_folder_fetch_data (imap_folder, uid, spec, FALSE, error);
+		stream = camel_imap_folder_fetch_data (imap_folder, uid, spec, FALSE, cancellable, error);
 		if (stream) {
 			ret = camel_data_wrapper_construct_from_stream (
-				CAMEL_DATA_WRAPPER (body_mp), stream, error);
+				CAMEL_DATA_WRAPPER (body_mp), stream, cancellable, error);
 			g_object_unref (CAMEL_OBJECT (stream));
 			if (ret == -1) {
 				g_object_unref ( body_mp);
@@ -3070,12 +3145,12 @@ get_content (CamelImapFolder *imap_folder, const gchar *uid,
 		num = 1;
 		while (ci) {
 			sprintf (child_spec + speclen, "%d.MIME", num++);
-			stream = camel_imap_folder_fetch_data (imap_folder, uid, child_spec, FALSE, error);
+			stream = camel_imap_folder_fetch_data (imap_folder, uid, child_spec, FALSE, cancellable, error);
 			if (stream) {
 				gint ret;
 
 				part = camel_mime_part_new ();
-				ret = camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (part), stream, error);
+				ret = camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (part), stream, cancellable, error);
 				g_object_unref (CAMEL_OBJECT (stream));
 				if (ret == -1) {
 					g_object_unref (CAMEL_OBJECT (part));
@@ -3084,7 +3159,7 @@ get_content (CamelImapFolder *imap_folder, const gchar *uid,
 					return NULL;
 				}
 
-				content = get_content (imap_folder, uid, part, ci, FALSE, error);
+				content = get_content (imap_folder, uid, part, ci, FALSE, cancellable, error);
 			}
 
 			if (!stream || !content) {
@@ -3126,7 +3201,7 @@ get_content (CamelImapFolder *imap_folder, const gchar *uid,
 
 		return (CamelDataWrapper *) body_mp;
 	} else if (camel_content_type_is (ci->type, "message", "rfc822")) {
-		content = (CamelDataWrapper *) get_message (imap_folder, uid, ci->childs, error);
+		content = (CamelDataWrapper *) get_message (imap_folder, uid, ci->childs, cancellable, error);
 		g_free (part_spec);
 		return content;
 	} else {
@@ -3148,9 +3223,11 @@ get_content (CamelImapFolder *imap_folder, const gchar *uid,
 }
 
 static CamelMimeMessage *
-get_message (CamelImapFolder *imap_folder, const gchar *uid,
-	     CamelMessageContentInfo *ci,
-	     GError **error)
+get_message (CamelImapFolder *imap_folder,
+             const gchar *uid,
+             CamelMessageContentInfo *ci,
+             GCancellable *cancellable,
+             GError **error)
 {
 	CamelFolder *folder;
 	CamelStore *parent_store;
@@ -3170,7 +3247,7 @@ get_message (CamelImapFolder *imap_folder, const gchar *uid,
 	section_text = g_strdup_printf ("%s%s%s", part_spec, *part_spec ? "." : "",
 					store->server_level >= IMAP_LEVEL_IMAP4REV1 ? "HEADER" : "0");
 
-	stream = camel_imap_folder_fetch_data (imap_folder, uid, section_text, FALSE, error);
+	stream = camel_imap_folder_fetch_data (imap_folder, uid, section_text, FALSE, cancellable, error);
 	g_free (section_text);
 	g_free (part_spec);
 	if (!stream)
@@ -3178,14 +3255,14 @@ get_message (CamelImapFolder *imap_folder, const gchar *uid,
 
 	msg = camel_mime_message_new ();
 	ret = camel_data_wrapper_construct_from_stream (
-		CAMEL_DATA_WRAPPER (msg), stream, error);
+		CAMEL_DATA_WRAPPER (msg), stream, cancellable, error);
 	g_object_unref (CAMEL_OBJECT (stream));
 	if (ret == -1) {
 		g_object_unref (CAMEL_OBJECT (msg));
 		return NULL;
 	}
 
-	content = get_content (imap_folder, uid, CAMEL_MIME_PART (msg), ci, TRUE, error);
+	content = get_content (imap_folder, uid, CAMEL_MIME_PART (msg), ci, TRUE, cancellable, error);
 	if (!content) {
 		g_object_unref (CAMEL_OBJECT (msg));
 		return NULL;
@@ -3210,22 +3287,25 @@ get_message (CamelImapFolder *imap_folder, const gchar *uid,
 #define IMAP_SMALL_BODY_SIZE 5120
 
 static CamelMimeMessage *
-get_message_simple (CamelImapFolder *imap_folder, const gchar *uid,
-		    CamelStream *stream, GError **error)
+get_message_simple (CamelImapFolder *imap_folder,
+                    const gchar *uid,
+                    CamelStream *stream,
+                    GCancellable *cancellable,
+                    GError **error)
 {
 	CamelMimeMessage *msg;
 	gint ret;
 
 	if (!stream) {
 		stream = camel_imap_folder_fetch_data (imap_folder, uid, "",
-						       FALSE, error);
+						       FALSE, cancellable, error);
 		if (!stream)
 			return NULL;
 	}
 
 	msg = camel_mime_message_new ();
 	ret = camel_data_wrapper_construct_from_stream (
-		CAMEL_DATA_WRAPPER (msg), stream, error);
+		CAMEL_DATA_WRAPPER (msg), stream, cancellable, error);
 	g_object_unref (CAMEL_OBJECT (stream));
 	if (ret == -1) {
 		g_prefix_error (error, _("Unable to retrieve message: "));
@@ -3272,6 +3352,7 @@ imap_folder_summary_uid_or_error (CamelFolderSummary *summary, const gchar * uid
 static CamelMimeMessage *
 imap_get_message (CamelFolder *folder,
                   const gchar *uid,
+                  GCancellable *cancellable,
                   GError **error)
 {
 	CamelStore *parent_store;
@@ -3293,9 +3374,9 @@ imap_get_message (CamelFolder *folder,
 	/* If its cached in full, just get it as is, this is only a shortcut,
 	 * since we get stuff from the cache anyway.  It affects a busted
 	 * connection though. */
-	stream = camel_imap_folder_fetch_data (imap_folder, uid, "", TRUE, NULL);
+	stream = camel_imap_folder_fetch_data (imap_folder, uid, "", TRUE, cancellable, NULL);
 	if (stream != NULL) {
-		msg = get_message_simple (imap_folder, uid, stream, NULL);
+		msg = get_message_simple (imap_folder, uid, stream, cancellable, NULL);
 		if (msg != NULL)
 			goto done;
 	}
@@ -3313,7 +3394,7 @@ imap_get_message (CamelFolder *folder,
 		    || mi->info.size < IMAP_SMALL_BODY_SIZE
 		    || (!content_info_incomplete (mi->info.content) && !mi->info.content->childs)) {
 			CamelMessageInfoBase *info = (CamelMessageInfoBase *) camel_folder_summary_uid (folder->summary, uid);
-			msg = get_message_simple (imap_folder, uid, NULL, &local_error);
+			msg = get_message_simple (imap_folder, uid, NULL, cancellable, &local_error);
 			if (info && !info->preview && msg && camel_folder_summary_get_need_preview (folder->summary)) {
 				if (camel_mime_message_build_preview ((CamelMimePart *)msg, (CamelMessageInfo *)info) && info->preview)
 					camel_folder_summary_add_preview (folder->summary, (CamelMessageInfo *)info);
@@ -3342,7 +3423,7 @@ imap_get_message (CamelFolder *folder,
 					goto fail;
 				}
 
-				response = camel_imap_command (store, folder, &local_error, "UID FETCH %s BODY", uid);
+				response = camel_imap_command (store, folder, cancellable, &local_error, "UID FETCH %s BODY", uid);
 				camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
 				if (response) {
@@ -3388,9 +3469,9 @@ imap_get_message (CamelFolder *folder,
 			 * let the mailer's "bad MIME" code handle it.
 			 */
 			if (content_info_incomplete (mi->info.content))
-				msg = get_message_simple (imap_folder, uid, NULL, &local_error);
+				msg = get_message_simple (imap_folder, uid, NULL, cancellable, &local_error);
 			else
-				msg = get_message (imap_folder, uid, mi->info.content, &local_error);
+				msg = get_message (imap_folder, uid, mi->info.content, cancellable, &local_error);
 			if (msg && camel_folder_summary_get_need_preview (folder->summary)) {
 				CamelMessageInfoBase *info = (CamelMessageInfoBase *) camel_folder_summary_uid (folder->summary, uid);
 				if (info && !info->preview) {
@@ -3459,6 +3540,7 @@ fail:
 static gboolean
 imap_sync_message (CamelFolder *folder,
                    const gchar *uid,
+                   GCancellable *cancellable,
                    GError **error)
 {
 	CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
@@ -3482,11 +3564,11 @@ imap_sync_message (CamelFolder *folder,
 	 */
 	/* If its cached in full, just get it as is, this is only a shortcut,
 	   since we get stuff from the cache anyway.  It affects a busted connection though. */
-	if ((stream = camel_imap_folder_fetch_data(imap_folder, uid, "", TRUE, NULL))) {
+	if ((stream = camel_imap_folder_fetch_data(imap_folder, uid, "", TRUE, cancellable, NULL))) {
 		g_object_unref (stream);
 		return TRUE;
 	}
-	msg = imap_get_message (folder, uid, error);
+	msg = imap_get_message (folder, uid, cancellable, error);
 	if (msg != NULL) {
 		g_object_unref (msg);
 		success = TRUE;
@@ -3616,8 +3698,11 @@ decode_internaldate (const guchar *in)
 }
 
 static void
-add_message_from_data (CamelFolder *folder, GPtrArray *messages,
-		       gint first, GData *data)
+add_message_from_data (CamelFolder *folder,
+                       GPtrArray *messages,
+                       gint first,
+                       GData *data,
+                       GCancellable *cancellable)
 {
 	CamelMimeMessage *msg;
 	CamelStream *stream;
@@ -3638,14 +3723,16 @@ add_message_from_data (CamelFolder *folder, GPtrArray *messages,
 
 	msg = camel_mime_message_new ();
 	if (camel_data_wrapper_construct_from_stream (
-		CAMEL_DATA_WRAPPER (msg), stream, NULL) == -1) {
+		CAMEL_DATA_WRAPPER (msg), stream, cancellable, NULL) == -1) {
 		g_object_unref (CAMEL_OBJECT (msg));
 		return;
 	}
 
 	bodystructure = g_datalist_get_data (&data, "BODY");
 
-	mi = (CamelImapMessageInfo *)camel_folder_summary_info_new_from_message (folder->summary, msg, bodystructure);
+	mi = (CamelImapMessageInfo *)
+		camel_folder_summary_info_new_from_message (
+		folder->summary, msg, bodystructure);
 	g_object_unref (CAMEL_OBJECT (msg));
 
 	if ((idate = g_datalist_get_data (&data, "INTERNALDATE")))
@@ -3743,6 +3830,7 @@ static gboolean
 imap_update_summary (CamelFolder *folder,
                      gint exists,
                      CamelFolderChangeInfo *changes,
+                     GCancellable *cancellable,
                      GError **error)
 {
 	CamelStore *parent_store;
@@ -3804,14 +3892,16 @@ imap_update_summary (CamelFolder *folder,
 		uidval = 0;
 
 	got = 0;
-	if (!camel_imap_command_start (store, folder, error,
+	if (!camel_imap_command_start (store, folder, cancellable, error,
 				       "UID FETCH %d:* (FLAGS RFC822.SIZE INTERNALDATE BODYSTRUCTURE BODY.PEEK[%s])",
 				       uidval + 1, header_spec->str)) {
 		g_string_free (header_spec, TRUE);
 		return FALSE;
 	}
+
 	camel_operation_start (
-		NULL, _("Fetching summary information for new messages in %s"),
+		cancellable,
+		_("Fetching summary information for new messages in %s"),
 		camel_folder_get_name (folder));
 
 	/* Parse the responses. We can't add a message to the summary
@@ -3821,7 +3911,7 @@ imap_update_summary (CamelFolder *folder,
 	fetch_data = g_ptr_array_new ();
 	messages = g_ptr_array_new ();
 	ct = exists - seq;
-	while ((type = camel_imap_command_response (store, &resp, error)) ==
+	while ((type = camel_imap_command_response (store, &resp, cancellable, error)) ==
 	       CAMEL_IMAP_RESPONSE_UNTAGGED && !camel_application_is_exiting) {
 		data = parse_fetch_response (imap_folder, resp);
 		g_free (resp);
@@ -3846,14 +3936,17 @@ imap_update_summary (CamelFolder *folder,
 			/* Use the stream now so we don't tie up many
 			 * many fds if we're fetching many many messages.
 			 */
-			add_message_from_data (folder, messages, first, data);
+			add_message_from_data (
+				folder, messages, first, data, cancellable);
 			g_datalist_set_data (&data, "BODY_PART_STREAM", NULL);
 		}
 
-		camel_operation_progress (NULL, k * 100 / ct);
+		camel_operation_progress (cancellable, k * 100 / ct);
+
 		g_ptr_array_add (fetch_data, data);
 	}
-	camel_operation_end (NULL);
+
+	camel_operation_end (cancellable);
 
 	if (type == CAMEL_IMAP_RESPONSE_ERROR || camel_application_is_exiting) {
 		if (type != CAMEL_IMAP_RESPONSE_ERROR && type != CAMEL_IMAP_RESPONSE_TAGGED)
@@ -3889,23 +3982,24 @@ imap_update_summary (CamelFolder *folder,
 		       sizeof (gpointer), uid_compar);
 
 		camel_operation_start (
-			NULL, _("Fetching summary information for new messages in %s"),
+			cancellable,
+			_("Fetching summary information for new messages in %s"),
 			camel_folder_get_name (folder));
 
 		while (uid < needheaders->len && !camel_application_is_exiting) {
 			uidset = imap_uid_array_to_set (folder->summary, needheaders, uid, UID_SET_LIMIT, &uid);
-			if (!camel_imap_command_start (store, folder, error,
+			if (!camel_imap_command_start (store, folder, cancellable, error,
 						       "UID FETCH %s BODYSTRUCTURE BODY.PEEK[%s]",
 						       uidset, header_spec->str)) {
 				g_ptr_array_free (needheaders, TRUE);
-				camel_operation_end (NULL);
+				camel_operation_end (cancellable);
 				g_free (uidset);
 				g_string_free (header_spec, TRUE);
 				goto lose;
 			}
 			g_free (uidset);
 
-			while ((type = camel_imap_command_response (store, &resp, error))
+			while ((type = camel_imap_command_response (store, &resp, cancellable, error))
 			       == CAMEL_IMAP_RESPONSE_UNTAGGED && !camel_application_is_exiting) {
 				data = parse_fetch_response (imap_folder, resp);
 				g_free (resp);
@@ -3914,16 +4008,19 @@ imap_update_summary (CamelFolder *folder,
 
 				stream = g_datalist_get_data (&data, "BODY_PART_STREAM");
 				if (stream) {
-					add_message_from_data (folder, messages, first, data);
+					add_message_from_data (
+						folder, messages, first,
+						data, cancellable);
 					got += IMAP_PRETEND_SIZEOF_HEADERS;
-					camel_operation_progress (NULL, got * 100 / size);
+					camel_operation_progress (
+						cancellable, got * 100 / size);
 				}
 				g_datalist_clear (&data);
 			}
 
 			if (type == CAMEL_IMAP_RESPONSE_ERROR || camel_application_is_exiting) {
 				g_ptr_array_free (needheaders, TRUE);
-				camel_operation_end (NULL);
+				camel_operation_end (cancellable);
 
 				if (type != CAMEL_IMAP_RESPONSE_ERROR && type != CAMEL_IMAP_RESPONSE_TAGGED)
 					camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
@@ -3933,7 +4030,7 @@ imap_update_summary (CamelFolder *folder,
 		}
 		g_string_free (header_spec, TRUE);
 		g_ptr_array_free (needheaders, TRUE);
-		camel_operation_end (NULL);
+		camel_operation_end (cancellable);
 	}
 
 	/* Now finish up summary entries (fix UIDs, set flags and size) */
@@ -4094,8 +4191,11 @@ imap_update_summary (CamelFolder *folder,
 
 /* Called with the store's connect_lock locked */
 gboolean
-camel_imap_folder_changed (CamelFolder *folder, gint exists,
-			   GArray *expunged, GError **error)
+camel_imap_folder_changed (CamelFolder *folder,
+                           gint exists,
+                           GArray *expunged,
+                           GCancellable *cancellable,
+                           GError **error)
 {
 	CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
 	CamelFolderChangeInfo *changes;
@@ -4137,7 +4237,8 @@ camel_imap_folder_changed (CamelFolder *folder, gint exists,
 
 	len = camel_folder_summary_count (folder->summary);
 	if (exists > len && !camel_application_is_exiting)
-		success = imap_update_summary (folder, exists, changes, error);
+		success = imap_update_summary (
+			folder, exists, changes, cancellable, error);
 
 	camel_folder_summary_save_to_db (folder->summary, NULL);
 	if (camel_folder_change_info_changed (changes))
@@ -4157,17 +4258,22 @@ imap_thaw (CamelFolder *folder)
 	if (camel_folder_is_frozen (folder))
 		return;
 
+	/* FIXME imap_refresh_info() may block, but camel_folder_thaw()
+	 *       is not supposed to block.  Potential hang here. */
 	imap_folder = CAMEL_IMAP_FOLDER (folder);
 	if (imap_folder->need_refresh) {
 		imap_folder->need_refresh = FALSE;
-		imap_refresh_info (folder, NULL);
+		imap_refresh_info (folder, NULL, NULL);
 	}
 }
 
 CamelStream *
-camel_imap_folder_fetch_data (CamelImapFolder *imap_folder, const gchar *uid,
-			      const gchar *section_text, gboolean cache_only,
-			      GError **error)
+camel_imap_folder_fetch_data (CamelImapFolder *imap_folder,
+                              const gchar *uid,
+                              const gchar *section_text,
+                              gboolean cache_only,
+                              GCancellable *cancellable,
+                              GError **error)
 {
 	CamelFolder *folder = CAMEL_FOLDER (imap_folder);
 	CamelStore *parent_store;
@@ -4216,11 +4322,11 @@ camel_imap_folder_fetch_data (CamelImapFolder *imap_folder, const gchar *uid,
 
 	if (store->server_level < IMAP_LEVEL_IMAP4REV1 && !*section_text) {
 		response = camel_imap_command (
-			store, folder, error,
+			store, folder, cancellable, error,
 			"UID FETCH %s RFC822.PEEK", uid);
 	} else {
 		response = camel_imap_command (
-			store, folder, error,
+			store, folder, cancellable, error,
 			"UID FETCH %s BODY.PEEK[%s]", uid,
 			section_text);
 	}
@@ -4393,7 +4499,7 @@ parse_fetch_response (CamelImapFolder *imap_folder, gchar *response)
 			CAMEL_IMAP_FOLDER_REC_LOCK (imap_folder, cache_lock);
 			stream = camel_imap_message_cache_insert (imap_folder->cache,
 								  uid, part_spec,
-								  body, body_len, NULL);
+								  body, body_len, NULL, NULL);
 			CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
 			if (stream == NULL)
 				stream = camel_stream_mem_new_with_buffer (body, body_len);
@@ -4432,7 +4538,7 @@ imap_get_quota_info (CamelFolder *folder)
 		CamelImapStoreNamespace *ns = camel_imap_store_summary_namespace_find_full (imap_store->summary, full_name);
 		gchar *folder_name = camel_imap_store_summary_path_to_full (imap_store->summary, full_name, ns ? ns->sep : '/');
 
-		response = camel_imap_command (imap_store, NULL, NULL, "GETQUOTAROOT \"%s\"", folder_name);
+		response = camel_imap_command (imap_store, NULL, NULL, NULL, "GETQUOTAROOT \"%s\"", folder_name);
 
 		if (response) {
 			gint i;
diff --git a/camel/providers/imap/camel-imap-folder.h b/camel/providers/imap/camel-imap-folder.h
index 25b1b6f..e24bd96 100644
--- a/camel/providers/imap/camel-imap-folder.h
+++ b/camel/providers/imap/camel-imap-folder.h
@@ -87,33 +87,40 @@ void		camel_imap_folder_set_check_folder
 						 gboolean check_folder);
 gboolean	camel_imap_folder_selected	(CamelFolder *folder,
 						 CamelImapResponse *response,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_imap_folder_changed	(CamelFolder *folder,
 						 gint exists,
 						 GArray *expunged,
+						 GCancellable *cancellable,
 						 GError **error);
 CamelStream *	camel_imap_folder_fetch_data	(CamelImapFolder *imap_folder,
 						 const gchar *uid,
 						 const gchar *section_text,
 						 gboolean cache_only,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_imap_append_resyncing	(CamelFolder *folder,
 						 CamelMimeMessage *message,
 						 const CamelMessageInfo *info,
 						 gchar **appended_uid,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_imap_transfer_resyncing	(CamelFolder *source,
 						 GPtrArray *uids,
 						 CamelFolder *dest,
 						 GPtrArray **transferred_uids,
 						 gboolean delete_originals,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_imap_expunge_uids_resyncing
 						(CamelFolder *folder,
 						 GPtrArray *uids,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_imap_expunge_uids_only	(CamelFolder *folder,
 						 GPtrArray *uids,
+						 GCancellable *cancellable,
 						 GError **error);
 
 G_END_DECLS
diff --git a/camel/providers/imap/camel-imap-journal.c b/camel/providers/imap/camel-imap-journal.c
index b7cc289..f0dac00 100644
--- a/camel/providers/imap/camel-imap-journal.c
+++ b/camel/providers/imap/camel-imap-journal.c
@@ -44,10 +44,9 @@
 static void imap_entry_free (CamelOfflineJournal *journal, CamelDListNode *entry);
 static CamelDListNode *imap_entry_load (CamelOfflineJournal *journal, FILE *in);
 static gint imap_entry_write (CamelOfflineJournal *journal, CamelDListNode *entry, FILE *out);
-static gint imap_entry_play (CamelOfflineJournal *journal, CamelDListNode *entry, GError **error);
+static gint imap_entry_play (CamelOfflineJournal *journal, CamelDListNode *entry, GCancellable *cancellable, GError **error);
 static void unref_folder (gpointer key, gpointer value, gpointer data);
 static void free_uids (GPtrArray *array);
-static void close_folder (gpointer name, gpointer folder, gpointer data);
 
 G_DEFINE_TYPE (CamelIMAPJournal, camel_imap_journal, CAMEL_TYPE_OFFLINE_JOURNAL)
 
@@ -275,7 +274,9 @@ imap_entry_write (CamelOfflineJournal *journal, CamelDListNode *entry, FILE *out
 }
 
 static CamelFolder *
-journal_decode_folder (CamelIMAPJournal *journal, const gchar *name)
+journal_decode_folder (CamelIMAPJournal *journal,
+                       const gchar *name,
+                       GCancellable *cancellable)
 {
 	CamelFolder *folder;
 	CamelOfflineJournal *offline = CAMEL_OFFLINE_JOURNAL (journal);
@@ -291,7 +292,8 @@ journal_decode_folder (CamelIMAPJournal *journal, const gchar *name)
 
 		parent_store = camel_folder_get_parent_store (
 			CAMEL_OFFLINE_JOURNAL (journal)->folder);
-		folder = camel_store_get_folder (parent_store, name, 0, &local_error);
+		folder = camel_store_get_folder (
+			parent_store, name, 0, cancellable, &local_error);
 		if (folder)
 			g_hash_table_insert (journal->folders, (gchar *) name, folder);
 		else {
@@ -310,7 +312,10 @@ journal_decode_folder (CamelIMAPJournal *journal, const gchar *name)
 }
 
 static gint
-imap_entry_play (CamelOfflineJournal *journal, CamelDListNode *entry, GError **error)
+imap_entry_play (CamelOfflineJournal *journal,
+                 CamelDListNode *entry,
+                 GCancellable *cancellable,
+                 GError **error)
 {
 	CamelIMAPJournalEntry *imap_entry = (CamelIMAPJournalEntry *) entry;
 
@@ -319,7 +324,7 @@ imap_entry_play (CamelOfflineJournal *journal, CamelDListNode *entry, GError **e
 	switch (imap_entry->type) {
 	case CAMEL_IMAP_JOURNAL_ENTRY_EXPUNGE:
 		camel_imap_expunge_uids_resyncing (
-			journal->folder, imap_entry->uids, NULL);
+			journal->folder, imap_entry->uids, cancellable, NULL);
 		return 0;
 	case CAMEL_IMAP_JOURNAL_ENTRY_APPEND:
 	{
@@ -327,7 +332,9 @@ imap_entry_play (CamelOfflineJournal *journal, CamelDListNode *entry, GError **e
 		CamelMimeMessage *message;
 		CamelMessageInfo *info;
 
-		message = camel_folder_get_message (journal->folder, imap_entry->append_uid, error);
+		message = camel_folder_get_message (
+			journal->folder, imap_entry->append_uid,
+			cancellable, error);
 		if (!message) {
 			/* it seems message gone, just ignore the error and continue;
 			   otherwise the entry would not be removed from the list */
@@ -337,7 +344,7 @@ imap_entry_play (CamelOfflineJournal *journal, CamelDListNode *entry, GError **e
 
 		info = camel_folder_get_message_info (journal->folder, imap_entry->append_uid);
 		camel_imap_append_resyncing (
-			journal->folder, message, info, &ret_uid, NULL);
+			journal->folder, message, info, &ret_uid, cancellable, NULL);
 		camel_folder_free_message_info (journal->folder, info);
 
 		if (ret_uid) {
@@ -353,7 +360,9 @@ imap_entry_play (CamelOfflineJournal *journal, CamelDListNode *entry, GError **e
 		GPtrArray *ret_uids;
 		gint i;
 
-		destination = journal_decode_folder ((CamelIMAPJournal *)journal, imap_entry->dest_folder_name);
+		destination = journal_decode_folder (
+			(CamelIMAPJournal *) journal,
+			imap_entry->dest_folder_name, cancellable);
 		if (!destination) {
 			d(g_print ("Destination folder not found \n"));
 			return -1;
@@ -361,7 +370,7 @@ imap_entry_play (CamelOfflineJournal *journal, CamelDListNode *entry, GError **e
 
 		if (!camel_imap_transfer_resyncing (
 			journal->folder, imap_entry->uids, destination,
-			&ret_uids, imap_entry->move, error))
+			&ret_uids, imap_entry->move, cancellable, error))
 			return -1;
 
 		if (ret_uids) {
@@ -445,10 +454,11 @@ camel_imap_journal_log (CamelOfflineJournal *journal, CamelOfflineAction action,
 }
 
 static void
-close_folder (gpointer name, gpointer folder, gpointer data)
+close_folder (gchar *name,
+              CamelFolder *folder)
 {
 	g_free (name);
-	camel_folder_sync (folder, FALSE, NULL);
+	camel_folder_sync (folder, FALSE, NULL, NULL);
 	g_object_unref (folder);
 }
 
@@ -459,7 +469,8 @@ camel_imap_journal_close_folders (CamelIMAPJournal *journal)
 	if (!journal->folders)
 		return;
 
-	g_hash_table_foreach (journal->folders, close_folder, journal);
+	g_hash_table_foreach (
+		journal->folders, (GHFunc) close_folder, NULL);
 	g_hash_table_remove_all (journal->folders);
 }
 
diff --git a/camel/providers/imap/camel-imap-journal.h b/camel/providers/imap/camel-imap-journal.h
index 8cc6f13..eb8c038 100644
--- a/camel/providers/imap/camel-imap-journal.h
+++ b/camel/providers/imap/camel-imap-journal.h
@@ -85,13 +85,19 @@ struct _CamelIMAPJournalClass {
 
 };
 
-GType camel_imap_journal_get_type (void);
-
-CamelOfflineJournal *camel_imap_journal_new (struct _CamelImapFolder *folder, const gchar *filename);
-void camel_imap_journal_log (CamelOfflineJournal *journal, CamelOfflineAction action, ...);
-void camel_imap_journal_uidmap_add (CamelIMAPJournal *journal, const gchar *old_uid, const gchar *n_uid);
-const gchar *camel_imap_journal_uidmap_lookup (CamelIMAPJournal *journal, const gchar *uid);
-void camel_imap_journal_close_folders (CamelIMAPJournal *journal);
+GType		camel_imap_journal_get_type (void);
+CamelOfflineJournal *
+		camel_imap_journal_new		(struct _CamelImapFolder *folder,
+						 const gchar *filename);
+void		camel_imap_journal_log		(CamelOfflineJournal *journal,
+						 CamelOfflineAction action,
+						 ...);
+void		camel_imap_journal_uidmap_add	(CamelIMAPJournal *journal,
+						 const gchar *old_uid,
+						 const gchar *n_uid);
+const gchar *	camel_imap_journal_uidmap_lookup(CamelIMAPJournal *journal,
+						 const gchar *uid);
+void		camel_imap_journal_close_folders(CamelIMAPJournal *journal);
 
 G_END_DECLS
 
diff --git a/camel/providers/imap/camel-imap-message-cache.c b/camel/providers/imap/camel-imap-message-cache.c
index 1b7f5b1..158064d 100644
--- a/camel/providers/imap/camel-imap-message-cache.c
+++ b/camel/providers/imap/camel-imap-message-cache.c
@@ -348,7 +348,7 @@ insert_finish (CamelImapMessageCache *cache,
                gchar *key,
                CamelStream *stream)
 {
-	camel_stream_flush (stream, NULL);
+	camel_stream_flush (stream, NULL, NULL);
 	camel_stream_reset (stream, NULL);
 	cache_put (cache, uid, key, stream);
 	g_free (path);
@@ -363,6 +363,8 @@ insert_finish (CamelImapMessageCache *cache,
  * @part_spec: the IMAP part_spec of the data
  * @data: the data
  * @len: length of @data
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
  *
  * Caches the provided data into @cache.
  *
@@ -375,6 +377,7 @@ camel_imap_message_cache_insert (CamelImapMessageCache *cache,
                                  const gchar *part_spec,
                                  const gchar *data,
                                  gint len,
+                                 GCancellable *cancellable,
                                  GError **error)
 {
 	gchar *path, *key;
@@ -384,7 +387,7 @@ camel_imap_message_cache_insert (CamelImapMessageCache *cache,
 	if (!stream)
 		return NULL;
 
-	if (camel_stream_write (stream, data, len, error) == -1) {
+	if (camel_stream_write (stream, data, len, cancellable, error) == -1) {
 		g_prefix_error (error, _("Failed to cache message %s: "), uid);
 		return insert_abort (path, stream);
 	}
@@ -414,7 +417,7 @@ camel_imap_message_cache_insert_stream (CamelImapMessageCache *cache,
 	if (!stream)
 		return;
 
-	if (camel_stream_write_to_stream (data_stream, stream, NULL) == -1) {
+	if (camel_stream_write_to_stream (data_stream, stream, NULL, NULL) == -1) {
 		insert_abort (path, stream);
 	} else {
 		insert_finish (cache, uid, path, key, stream);
@@ -444,7 +447,7 @@ camel_imap_message_cache_insert_wrapper (CamelImapMessageCache *cache,
 	if (!stream)
 		return;
 
-	if (camel_data_wrapper_write_to_stream (wrapper, stream, NULL) == -1) {
+	if (camel_data_wrapper_write_to_stream (wrapper, stream, NULL, NULL) == -1) {
 		insert_abort (path, stream);
 	} else {
 		insert_finish (cache, uid, path, key, stream);
diff --git a/camel/providers/imap/camel-imap-message-cache.h b/camel/providers/imap/camel-imap-message-cache.h
index adb59f4..31fd81b 100644
--- a/camel/providers/imap/camel-imap-message-cache.h
+++ b/camel/providers/imap/camel-imap-message-cache.h
@@ -85,6 +85,7 @@ CamelStream *camel_imap_message_cache_insert (CamelImapMessageCache *cache,
 					      const gchar *part_spec,
 					      const gchar *data,
 					      gint len,
+					      GCancellable *cancellable,
 					      GError **error);
 void camel_imap_message_cache_insert_stream  (CamelImapMessageCache *cache,
 					      const gchar *uid,
diff --git a/camel/providers/imap/camel-imap-search.c b/camel/providers/imap/camel-imap-search.c
index b0ecfc9..1d9a9d5 100644
--- a/camel/providers/imap/camel-imap-search.c
+++ b/camel/providers/imap/camel-imap-search.c
@@ -243,10 +243,10 @@ save_match (CamelImapSearch *is, struct _match_record *mr)
 	header.lastuid = mr->lastuid;
 	header.validity = mr->validity;
 
-	if (camel_stream_write (stream, (gchar *)&header, sizeof (header), NULL) != sizeof (header)
-	    || camel_stream_write (stream, mr->matches->data, mr->matches->len*sizeof (guint32), NULL) != mr->matches->len*sizeof (guint32)
+	if (camel_stream_write (stream, (gchar *)&header, sizeof (header), NULL, NULL) != sizeof (header)
+	    || camel_stream_write (stream, mr->matches->data, mr->matches->len*sizeof (guint32), NULL, NULL) != mr->matches->len*sizeof (guint32)
 	    || camel_seekable_stream_seek ((CamelSeekableStream *)stream, 0, CAMEL_STREAM_SET, NULL) == -1
-	    || camel_stream_write (stream, (gchar *)&mark, sizeof (mark), NULL) != sizeof (mark)) {
+	    || camel_stream_write (stream, (gchar *)&mark, sizeof (mark), NULL, NULL) != sizeof (mark)) {
 		d(printf(" saving failed, removing cache entry\n"));
 		camel_data_cache_remove(is->cache, "search/body-contains", mr->hash, NULL);
 		ret = -1;
@@ -287,13 +287,13 @@ load_match (CamelImapSearch *is, gchar hash[17], gint argc, struct _ESExpResult
 		   should be sufficient to key it */
 		/* This check should also handle endianness changes, we just throw away
 		   the data (its only a cache) */
-		if (camel_stream_read (stream, (gchar *)&header, sizeof (header), NULL) == sizeof (header)
+		if (camel_stream_read (stream, (gchar *)&header, sizeof (header), NULL, NULL) == sizeof (header)
 		    && header.validity == is->validity
 		    && header.mark == MATCH_MARK
 		    && header.termcount == 0) {
 			d(printf(" found %d matches\n", header.matchcount));
 			g_array_set_size (mr->matches, header.matchcount);
-			camel_stream_read (stream, mr->matches->data, sizeof (guint32)*header.matchcount, NULL);
+			camel_stream_read (stream, mr->matches->data, sizeof (guint32)*header.matchcount, NULL, NULL);
 		} else {
 			d(printf(" file format invalid/validity changed\n"));
 			memset (&header, 0, sizeof (header));
@@ -354,14 +354,14 @@ sync_match (CamelImapSearch *is, struct _match_record *mr)
 
 	/* We only try search using utf8 if its non us-ascii text? */
 	if ((words->type & CAMEL_SEARCH_WORD_8BIT) &&  (store->capabilities & IMAP_CAPABILITY_utf8_search)) {
-		response = camel_imap_command (store, folder, NULL,
+		response = camel_imap_command (store, folder, NULL, NULL,
 					       "UID SEARCH CHARSET UTF-8 %s", search->str);
 		/* We can't actually tell if we got a NO response, so assume always */
 		if (response == NULL)
 			store->capabilities &= ~IMAP_CAPABILITY_utf8_search;
 	}
 	if (response == NULL)
-		response = camel_imap_command (store, folder, NULL,
+		response = camel_imap_command (store, folder, NULL, NULL,
 					       "UID SEARCH %s", search->str);
 	g_string_free (search, TRUE);
 
diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c
index 00ca4db..e852154 100644
--- a/camel/providers/imap/camel-imap-store.c
+++ b/camel/providers/imap/camel-imap-store.c
@@ -66,29 +66,22 @@ extern gint camel_verbose_debug;
 
 static gchar imap_tag_prefix = 'A';
 
-static gboolean construct (CamelService *service, CamelSession *session,
-		       CamelProvider *provider, CamelURL *url,
-		       GError **error);
-
-static gchar *imap_get_name (CamelService *service, gboolean brief);
-
-static gboolean imap_noop (CamelStore *store, GError **error);
-static CamelFolder *imap_get_junk (CamelStore *store, GError **error);
-static CamelFolder *imap_get_trash (CamelStore *store, GError **error);
-static GList *query_auth_types (CamelService *service, GError **error);
+static gboolean imap_noop (CamelStore *store, GCancellable *cancellable, GError **error);
+static CamelFolder *imap_get_junk(CamelStore *store, GCancellable *cancellable, GError **error);
+static CamelFolder *imap_get_trash(CamelStore *store, GCancellable *cancellable, GError **error);
 static guint hash_folder_name (gconstpointer key);
 static gint compare_folder_name (gconstpointer a, gconstpointer b);
 
-static CamelFolderInfo *create_folder (CamelStore *store, const gchar *parent_name, const gchar *folder_name, GError **error);
-static gboolean delete_folder (CamelStore *store, const gchar *folder_name, GError **error);
-static gboolean rename_folder (CamelStore *store, const gchar *old_name, const gchar *new_name, GError **error);
+static CamelFolderInfo *create_folder (CamelStore *store, const gchar *parent_name, const gchar *folder_name, GCancellable *cancellable, GError **error);
+static gboolean delete_folder (CamelStore *store, const gchar *folder_name, GCancellable *cancellable, GError **error);
+static gboolean rename_folder (CamelStore *store, const gchar *old_name, const gchar *new_name, GCancellable *cancellable, GError **error);
 static gboolean folder_is_subscribed (CamelStore *store, const gchar *folder_name);
 static gboolean subscribe_folder (CamelStore *store, const gchar *folder_name,
-			      GError **error);
+			      GCancellable *cancellable, GError **error);
 static gboolean unsubscribe_folder (CamelStore *store, const gchar *folder_name,
-				GError **error);
+			      GCancellable *cancellable, GError **error);
 
-static gboolean get_folders_sync (CamelImapStore *imap_store, const gchar *pattern, GError **error);
+static gboolean get_folders_sync (CamelImapStore *imap_store, const gchar *pattern, GCancellable *cancellable, GError **error);
 
 static gboolean imap_folder_effectively_unsubscribed (CamelImapStore *imap_store, const gchar *folder_name, GError **error);
 static gboolean imap_check_folder_still_extant (CamelImapStore *imap_store, const gchar *full_name,  GError **error);
@@ -96,234 +89,34 @@ static void imap_forget_folder (CamelImapStore *imap_store, const gchar *folder_
 static void imap_set_server_level (CamelImapStore *store);
 
 static gboolean imap_can_refresh_folder (CamelStore *store, CamelFolderInfo *info, GError **error);
-static gboolean imap_connect (CamelService *service, GError **error);
-static gboolean imap_disconnect (CamelService *service, gboolean clean, GError **error);
-static CamelFolder * get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError **error);
-static CamelFolderInfo * get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GError **error);
+static CamelFolder * get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GCancellable *cancellable, GError **error);
+static CamelFolderInfo * get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GCancellable *cancellable, GError **error);
 static CamelFolder * get_folder_offline (CamelStore *store, const gchar *folder_name, guint32 flags, GError **error);
 static CamelFolderInfo * get_folder_info_offline (CamelStore *store, const gchar *top, guint32 flags, GError **error);
 
-G_DEFINE_TYPE (CamelImapStore, camel_imap_store, CAMEL_TYPE_OFFLINE_STORE)
-
-static gboolean
-free_key (gpointer key, gpointer value, gpointer user_data)
-{
-	g_free (key);
-	return TRUE;
-}
-
-static void
-imap_store_dispose (GObject *object)
-{
-	CamelImapStore *imap_store = CAMEL_IMAP_STORE (object);
-
-	if (imap_store->summary != NULL) {
-		camel_store_summary_save (
-			CAMEL_STORE_SUMMARY (imap_store->summary));
-		g_object_unref (imap_store->summary);
-		imap_store->summary = NULL;
-	}
-
-	/* Chain up to parent's dispose() method. */
-	G_OBJECT_CLASS (camel_imap_store_parent_class)->dispose (object);
-}
-
-static void
-imap_store_finalize (GObject *object)
-{
-	CamelImapStore *imap_store = CAMEL_IMAP_STORE (object);
-
-	/* This frees current_folder, folders, authtypes, streams, and namespace. */
-	camel_service_disconnect (CAMEL_SERVICE (imap_store), TRUE, NULL);
-
-	g_free (imap_store->base_url);
-	g_free (imap_store->storage_path);
-	g_free (imap_store->users_namespace);
-	g_free (imap_store->custom_headers);
-	g_free (imap_store->real_trash_path);
-	g_free (imap_store->real_junk_path);
-
-	/* Chain up to parent's finalize() method. */
-	G_OBJECT_CLASS (camel_imap_store_parent_class)->finalize (object);
-}
-
-static void
-camel_imap_store_class_init (CamelImapStoreClass *class)
-{
-	GObjectClass *object_class;
-	CamelServiceClass *service_class;
-	CamelStoreClass *store_class;
-
-	object_class = G_OBJECT_CLASS (class);
-	object_class->dispose = imap_store_dispose;
-	object_class->finalize = imap_store_finalize;
-
-	service_class = CAMEL_SERVICE_CLASS (class);
-	service_class->construct = construct;
-	service_class->query_auth_types = query_auth_types;
-	service_class->get_name = imap_get_name;
-	service_class->connect = imap_connect;
-	service_class->disconnect = imap_disconnect;
-
-	store_class = CAMEL_STORE_CLASS (class);
-	store_class->hash_folder_name = hash_folder_name;
-	store_class->compare_folder_name = compare_folder_name;
-	store_class->get_folder = get_folder;
-	store_class->create_folder = create_folder;
-	store_class->delete_folder = delete_folder;
-	store_class->rename_folder = rename_folder;
-	store_class->get_folder_info = get_folder_info;
-	store_class->free_folder_info = camel_store_free_folder_info_full;
-	store_class->folder_is_subscribed = folder_is_subscribed;
-	store_class->subscribe_folder = subscribe_folder;
-	store_class->unsubscribe_folder = unsubscribe_folder;
-	store_class->noop = imap_noop;
-	store_class->get_trash = imap_get_trash;
-	store_class->get_junk = imap_get_junk;
-	store_class->can_refresh_folder = imap_can_refresh_folder;
-}
-
-static void
-camel_imap_store_init (CamelImapStore *imap_store)
-{
-	imap_store->istream = NULL;
-	imap_store->ostream = NULL;
-
-	/* TODO: support dir_sep per namespace */
-	imap_store->dir_sep = '\0';
-	imap_store->current_folder = NULL;
-	imap_store->connected = FALSE;
-	imap_store->preauthed = FALSE;
-	((CamelStore *)imap_store)->flags |= CAMEL_STORE_SUBSCRIPTIONS;
-
-	imap_store->tag_prefix = imap_tag_prefix++;
-	if (imap_tag_prefix > 'Z')
-		imap_tag_prefix = 'A';
-}
-
-static gboolean
-construct (CamelService *service, CamelSession *session,
-	   CamelProvider *provider, CamelURL *url,
-	   GError **error)
-{
-	CamelServiceClass *service_class;
-	CamelImapStore *imap_store = CAMEL_IMAP_STORE (service);
-	CamelStore *store = CAMEL_STORE (service);
-	gchar *tmp;
-	CamelURL *summary_url;
-
-	/* Chain up to parent's construct() method. */
-	service_class = CAMEL_SERVICE_CLASS (camel_imap_store_parent_class);
-	if (!service_class->construct (service, session, provider, url, error))
-		return FALSE;
-
-	imap_store->storage_path = camel_session_get_storage_path (session, service, error);
-	if (!imap_store->storage_path)
-		return FALSE;
-
-	/* FIXME */
-	imap_store->base_url = camel_url_to_string (service->url, (CAMEL_URL_HIDE_PASSWORD |
-								   CAMEL_URL_HIDE_PARAMS |
-								   CAMEL_URL_HIDE_AUTH));
-
-	imap_store->parameters = 0;
-	if (camel_url_get_param (url, "use_lsub"))
-		imap_store->parameters |= IMAP_PARAM_SUBSCRIPTIONS;
-	if (camel_url_get_param (url, "override_namespace") && camel_url_get_param (url, "namespace")) {
-		imap_store->parameters |= IMAP_PARAM_OVERRIDE_NAMESPACE;
-		g_free (imap_store->users_namespace);
-		imap_store->users_namespace = g_strdup (camel_url_get_param (url, "namespace"));
-	}
-	if (camel_url_get_param (url, "check_all"))
-		imap_store->parameters |= IMAP_PARAM_CHECK_ALL;
-	if (camel_url_get_param (url, "check_lsub"))
-		imap_store->parameters |= IMAP_PARAM_CHECK_LSUB;
-	if (camel_url_get_param (url, "filter")) {
-		imap_store->parameters |= IMAP_PARAM_FILTER_INBOX;
-		store->flags |= CAMEL_STORE_FILTER_INBOX;
-	}
-	if (camel_url_get_param (url, "filter_junk"))
-		imap_store->parameters |= IMAP_PARAM_FILTER_JUNK;
-	if (camel_url_get_param (url, "filter_junk_inbox"))
-		imap_store->parameters |= IMAP_PARAM_FILTER_JUNK_INBOX;
-
-	imap_store->headers = IMAP_FETCH_MAILING_LIST_HEADERS;
-	if (camel_url_get_param (url, "all_headers"))
-		imap_store->headers = IMAP_FETCH_ALL_HEADERS;
-	else if (camel_url_get_param (url, "basic_headers"))
-		imap_store->headers = IMAP_FETCH_MINIMAL_HEADERS;
-
-	if (camel_url_get_param (url, "imap_custom_headers")) {
-		imap_store->custom_headers = g_strdup(camel_url_get_param (url, "imap_custom_headers"));
-	}
-
-	imap_store->real_trash_path = g_strdup (camel_url_get_param (url, "real_trash_path"));
-	imap_store->real_junk_path = g_strdup (camel_url_get_param (url, "real_junk_path"));
-
-	if (imap_store->real_trash_path && !*imap_store->real_trash_path) {
-		g_free (imap_store->real_trash_path);
-		imap_store->real_trash_path = NULL;
-	}
-
-	if (imap_store->real_trash_path && *imap_store->real_trash_path)
-		store->flags &= ~CAMEL_STORE_VTRASH;
-
-	if (imap_store->real_junk_path && !*imap_store->real_junk_path) {
-		g_free (imap_store->real_junk_path);
-		imap_store->real_junk_path = NULL;
-	}
-
-	if (imap_store->real_junk_path && *imap_store->real_junk_path) {
-		store->flags &= ~CAMEL_STORE_VJUNK;
-		store->flags |= CAMEL_STORE_REAL_JUNK_FOLDER;
-	}
-
-	/* setup/load the store summary */
-	tmp = alloca (strlen (imap_store->storage_path)+32);
-	sprintf(tmp, "%s/.ev-store-summary", imap_store->storage_path);
-	imap_store->summary = camel_imap_store_summary_new ();
-	camel_store_summary_set_filename ((CamelStoreSummary *)imap_store->summary, tmp);
-	summary_url = camel_url_new (imap_store->base_url, NULL);
-	camel_store_summary_set_uri_base ((CamelStoreSummary *)imap_store->summary, summary_url);
-	camel_url_free (summary_url);
-	if (camel_store_summary_load ((CamelStoreSummary *)imap_store->summary) == 0) {
-		CamelImapStoreSummary *is = imap_store->summary;
-
-		if (is->namespace) {
-			/* if namespace has changed, clear folder list */
-			if (imap_store->users_namespace && strcmp (imap_store->users_namespace, is->namespace->full_name) != 0) {
-				camel_store_summary_clear ((CamelStoreSummary *)is);
-			}
-		}
-
-		imap_store->capabilities = is->capabilities;
-		imap_set_server_level (imap_store);
-	}
-
-	return TRUE;
-}
+enum {
+	MODE_CLEAR,
+	MODE_SSL,
+	MODE_TLS
+};
 
-static gchar *
-imap_get_name (CamelService *service, gboolean brief)
-{
-	if (brief)
-		return g_strdup_printf (_("IMAP server %s"), service->url->host);
-	else
-		return g_strdup_printf (_("IMAP service for %s on %s"),
-					service->url->user, service->url->host);
-}
+#ifdef HAVE_SSL
+#define SSL_PORT_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3)
+#define STARTTLS_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_TLS)
+#endif
 
-static void
-imap_set_server_level (CamelImapStore *store)
-{
-	if (store->capabilities & IMAP_CAPABILITY_IMAP4REV1) {
-		store->server_level = IMAP_LEVEL_IMAP4REV1;
-		store->capabilities |= IMAP_CAPABILITY_STATUS;
-	} else if (store->capabilities & IMAP_CAPABILITY_IMAP4)
-		store->server_level = IMAP_LEVEL_IMAP4;
-	else
-		store->server_level = IMAP_LEVEL_UNKNOWN;
-}
+static struct {
+	const gchar *value;
+	const gchar *serv;
+	gint fallback_port;
+	gint mode;
+} ssl_options[] = {
+	{ "",              "imaps", IMAPS_PORT, MODE_SSL   },  /* really old (1.x) */
+	{ "always",        "imaps", IMAPS_PORT, MODE_SSL   },
+	{ "when-possible", "imap",  IMAP_PORT,  MODE_TLS   },
+	{ "never",         "imap",  IMAP_PORT,  MODE_CLEAR },
+	{ NULL,            "imap",  IMAP_PORT,  MODE_CLEAR },
+};
 
 static struct {
 	const gchar *name;
@@ -343,6 +136,10 @@ static struct {
 	{ NULL, 0 }
 };
 
+extern CamelServiceAuthType camel_imap_password_authtype;
+
+G_DEFINE_TYPE (CamelImapStore, camel_imap_store, CAMEL_TYPE_OFFLINE_STORE)
+
 static void
 parse_capability (CamelImapStore *store, gchar *capa)
 {
@@ -366,7 +163,9 @@ parse_capability (CamelImapStore *store, gchar *capa)
 }
 
 static gboolean
-imap_get_capability (CamelService *service, GError **error)
+imap_get_capability (CamelService *service,
+                     GCancellable *cancellable,
+                     GError **error)
 {
 	CamelImapStore *store = CAMEL_IMAP_STORE (service);
 	CamelImapResponse *response;
@@ -376,7 +175,7 @@ imap_get_capability (CamelService *service, GError **error)
 	/* We assume we have utf8 capable search until a failed search tells us otherwise */
 	store->capabilities = IMAP_CAPABILITY_utf8_search;
 	store->authtypes = g_hash_table_new (g_str_hash, g_str_equal);
-	response = camel_imap_command (store, NULL, error, "CAPABILITY");
+	response = camel_imap_command (store, NULL, cancellable, error, "CAPABILITY");
 	if (!response)
 		return FALSE;
 	result = camel_imap_response_extract (store, response, "CAPABILITY ", error);
@@ -390,7 +189,7 @@ imap_get_capability (CamelService *service, GError **error)
 	/* dunno why the groupwise guys didn't just list this in capabilities */
 	if (store->capabilities & IMAP_CAPABILITY_XGWEXTENSIONS) {
 		/* not critical if this fails */
-		response = camel_imap_command (store, NULL, NULL, "XGWEXTENSIONS");
+		response = camel_imap_command (store, NULL, cancellable, NULL, "XGWEXTENSIONS");
 		if (response && (result = camel_imap_response_extract (store, response, "XGWEXTENSIONS ", NULL))) {
 			parse_capability (store, result+16);
 			g_free (result);
@@ -408,12 +207,6 @@ imap_get_capability (CamelService *service, GError **error)
 	return TRUE;
 }
 
-enum {
-	MODE_CLEAR,
-	MODE_SSL,
-	MODE_TLS
-};
-
 #ifdef CAMEL_HAVE_SSL
 #define SSL_PORT_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3)
 #define STARTTLS_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_TLS)
@@ -421,7 +214,12 @@ enum {
 
 static gboolean
 connect_to_server (CamelService *service,
-		   const gchar *host, const gchar *serv, gint fallback_port, gint ssl_mode, GError **error)
+                   const gchar *host,
+                   const gchar *serv,
+                   gint fallback_port,
+                   gint ssl_mode,
+                   GCancellable *cancellable,
+                   GError **error)
 {
 	CamelImapStore *store = (CamelImapStore *) service;
 	CamelSession *session;
@@ -461,7 +259,9 @@ connect_to_server (CamelService *service,
 		g_free (socks_host);
 	}
 
-	if (camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, host, serv, fallback_port, error) == -1) {
+	if (camel_tcp_stream_connect (
+		CAMEL_TCP_STREAM (tcp_stream), host, serv,
+		fallback_port, cancellable, error) == -1) {
 		g_prefix_error (
 			error, _("Could not connect to %s: "),
 			service->url->host);
@@ -487,7 +287,7 @@ connect_to_server (CamelService *service,
 	camel_tcp_stream_setsockopt ((CamelTcpStream *)tcp_stream, &sockopt);
 
 	/* Read the greeting, if any, and deal with PREAUTH */
-	if (camel_imap_store_readline (store, &buf, error) < 0) {
+	if (camel_imap_store_readline (store, &buf, cancellable, error) < 0) {
 		if (store->istream) {
 			g_object_unref (store->istream);
 			store->istream = NULL;
@@ -537,7 +337,7 @@ connect_to_server (CamelService *service,
 	g_free (buf);
 
 	/* get the imap server capabilities */
-	if (!imap_get_capability (service, error)) {
+	if (!imap_get_capability (service, cancellable, error)) {
 		if (store->istream) {
 			g_object_unref (store->istream);
 			store->istream = NULL;
@@ -575,7 +375,7 @@ connect_to_server (CamelService *service,
 		goto exception;
 	}
 
-	response = camel_imap_command (store, NULL, error, "STARTTLS");
+	response = camel_imap_command (store, NULL, cancellable, error, "STARTTLS");
 	if (!response) {
 		g_object_unref (store->istream);
 		g_object_unref (store->ostream);
@@ -603,7 +403,7 @@ connect_to_server (CamelService *service,
 
 	/* rfc2595, section 4 states that after a successful STLS
            command, the client MUST discard prior CAPA responses */
-	if (!imap_get_capability (service, error)) {
+	if (!imap_get_capability (service, cancellable, error)) {
 		if (store->istream) {
 			g_object_unref (store->istream);
 			store->istream = NULL;
@@ -634,7 +434,7 @@ exception:
 
 	if (clean_quit && store->connected) {
 		/* try to disconnect cleanly */
-		response = camel_imap_command (store, NULL, error, "LOGOUT");
+		response = camel_imap_command (store, NULL, cancellable, error, "LOGOUT");
 		if (response)
 			camel_imap_response_free_without_processing (store, response);
 	}
@@ -659,7 +459,10 @@ exception:
 /* Using custom commands to connect to IMAP servers is not supported on Win32 */
 
 static gboolean
-connect_to_server_process (CamelService *service, const gchar *cmd, GError **error)
+connect_to_server_process (CamelService *service,
+                           const gchar *cmd,
+                           GCancellable *cancellable,
+                           GError **error)
 {
 	CamelImapStore *store = (CamelImapStore *) service;
 	CamelStream *cmd_stream;
@@ -767,7 +570,7 @@ connect_to_server_process (CamelService *service, const gchar *cmd, GError **err
 	store->command = 0;
 
 	/* Read the greeting, if any, and deal with PREAUTH */
-	if (camel_imap_store_readline (store, &buf, error) < 0) {
+	if (camel_imap_store_readline (store, &buf, cancellable, error) < 0) {
 		if (store->istream) {
 			g_object_unref (store->istream);
 			store->istream = NULL;
@@ -787,7 +590,7 @@ connect_to_server_process (CamelService *service, const gchar *cmd, GError **err
 	g_free (buf);
 
 	/* get the imap server capabilities */
-	if (!imap_get_capability (service, error)) {
+	if (!imap_get_capability (service, cancellable, error)) {
 		if (store->istream) {
 			g_object_unref (store->istream);
 			store->istream = NULL;
@@ -808,21 +611,10 @@ connect_to_server_process (CamelService *service, const gchar *cmd, GError **err
 
 #endif
 
-static struct {
-	const gchar *value;
-	const gchar *serv;
-	gint fallback_port;
-	gint mode;
-} ssl_options[] = {
-	{ "",              "imaps", IMAPS_PORT, MODE_SSL   },  /* really old (1.x) */
-	{ "always",        "imaps", IMAPS_PORT, MODE_SSL   },
-	{ "when-possible", "imap",  IMAP_PORT,  MODE_TLS   },
-	{ "never",         "imap",  IMAP_PORT,  MODE_CLEAR },
-	{ NULL,            "imap",  IMAP_PORT,  MODE_CLEAR },
-};
-
 static gboolean
-connect_to_server_wrapper (CamelService *service, GError **error)
+connect_to_server_wrapper (CamelService *service,
+                           GCancellable *cancellable,
+                           GError **error)
 {
 	const gchar *ssl_mode;
 	gint mode, i;
@@ -834,7 +626,7 @@ connect_to_server_wrapper (CamelService *service, GError **error)
 
 	if (camel_url_get_param(service->url, "use_command")
 	    && (command = camel_url_get_param(service->url, "command")))
-		return connect_to_server_process (service, command, error);
+		return connect_to_server_process (service, command, cancellable, error);
 #endif
 
 	if ((ssl_mode = camel_url_get_param (service->url, "use_ssl"))) {
@@ -856,205 +648,23 @@ connect_to_server_wrapper (CamelService *service, GError **error)
 		fallback_port = 0;
 	}
 
-	return connect_to_server (service, service->url->host, serv, fallback_port, mode, error);
-}
-
-extern CamelServiceAuthType camel_imap_password_authtype;
-
-static GList *
-query_auth_types (CamelService *service, GError **error)
-{
-	CamelImapStore *store = CAMEL_IMAP_STORE (service);
-	CamelServiceAuthType *authtype;
-	GList *sasl_types, *t, *next;
-	gboolean connected;
-
-	if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
-		g_set_error (
-			error, CAMEL_SERVICE_ERROR,
-			CAMEL_SERVICE_ERROR_UNAVAILABLE,
-			_("You must be working online to complete this operation"));
-		return NULL;
-	}
-
-	camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-	connected = store->istream != NULL && store->connected;
-	if (!connected)
-		connected = connect_to_server_wrapper (service, error);
-	camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-	if (!connected)
-		return NULL;
-
-	sasl_types = camel_sasl_authtype_list (FALSE);
-	for (t = sasl_types; t; t = next) {
-		authtype = t->data;
-		next = t->next;
-
-		if (!g_hash_table_lookup (store->authtypes, authtype->authproto)) {
-			sasl_types = g_list_remove_link (sasl_types, t);
-			g_list_free_1 (t);
-		}
-	}
-
-	return g_list_prepend (sasl_types, &camel_imap_password_authtype);
-}
-
-/* folder_name is path name */
-static CamelFolderInfo *
-imap_build_folder_info (CamelImapStore *imap_store, const gchar *folder_name)
-{
-	CamelURL *url;
-	const gchar *name;
-	CamelFolderInfo *fi;
-
-	fi = camel_folder_info_new ();
-	fi->full_name = g_strdup (folder_name);
-	fi->unread = -1;
-	fi->total = -1;
-
-	url = camel_url_new (imap_store->base_url, NULL);
-	g_free (url->path);
-	url->path = g_strdup_printf ("/%s", folder_name);
-	fi->uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
-	camel_url_free (url);
-	name = strrchr (fi->full_name, '/');
-	if (name == NULL)
-		name = fi->full_name;
-	else
-		name++;
-	if (!g_ascii_strcasecmp (fi->full_name, "INBOX"))
-		fi->name = g_strdup (_("Inbox"));
-	/* Do not localize the rest, these are from a server, thus shouldn't be localized */
-	/*else if (!g_ascii_strcasecmp (fi->full_name, "Drafts"))
-		fi->name = g_strdup (_("Drafts"));
-	else if (!g_ascii_strcasecmp (fi->full_name, "Sent"))
-		fi->name = g_strdup (_("Sent"));
-	else if (!g_ascii_strcasecmp (fi->full_name, "Templates"))
-		fi->name = g_strdup (_("Templates"));
-	else if (!g_ascii_strcasecmp (fi->full_name, "Trash"))
-		fi->name = g_strdup (_("Trash"));*/
-	else
-		fi->name = g_strdup (name);
-
-	return fi;
-}
-
-static gboolean
-imap_folder_effectively_unsubscribed (CamelImapStore *imap_store,
-                                      const gchar *folder_name,
-                                      GError **error)
-{
-	CamelFolderInfo *fi;
-	CamelStoreInfo *si;
-
-	si = camel_store_summary_path ((CamelStoreSummary *)imap_store->summary, folder_name);
-	if (si) {
-		if (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) {
-			si->flags &= ~CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
-			camel_store_summary_touch ((CamelStoreSummary *)imap_store->summary);
-			camel_store_summary_save ((CamelStoreSummary *)imap_store->summary);
-		}
-		camel_store_summary_info_free ((CamelStoreSummary *)imap_store->summary, si);
-	}
-
-	if (imap_store->renaming) {
-		/* we don't need to emit a "folder_unsubscribed" signal
-                   if we are in the process of renaming folders, so we
-                   are done here... */
-		return TRUE;
-
-	}
-
-	fi = imap_build_folder_info (imap_store, folder_name);
-	camel_store_folder_unsubscribed (CAMEL_STORE (imap_store), fi);
-	camel_folder_info_free (fi);
-
-	return TRUE;
-}
-
-static void
-imap_forget_folder (CamelImapStore *imap_store, const gchar *folder_name, GError **error)
-{
-	gchar *state_file;
-	gchar *journal_file;
-	gchar *folder_dir, *storage_path;
-	CamelFolderInfo *fi;
-	const gchar *name;
-
-	name = strrchr (folder_name, imap_store->dir_sep);
-	if (name)
-		name++;
-	else
-		name = folder_name;
-
-	storage_path = g_strdup_printf ("%s/folders", imap_store->storage_path);
-	folder_dir = imap_path_to_physical (storage_path, folder_name);
-	g_free (storage_path);
-	if (g_access (folder_dir, F_OK) != 0) {
-		g_free (folder_dir);
-		goto event;
-	}
-
-	/* Delete summary and all the data */
-	journal_file = g_strdup_printf ("%s/journal", folder_dir);
-	g_unlink (journal_file);
-	g_free (journal_file);
-
-	state_file = g_strdup_printf ("%s/cmeta", folder_dir);
-	g_unlink (state_file);
-	g_free (state_file);
-
-	camel_db_delete_folder (((CamelStore *)imap_store)->cdb_w, folder_name, NULL);
-	camel_imap_message_cache_delete (folder_dir, NULL);
-
-	state_file = g_strdup_printf("%s/subfolders", folder_dir);
-	g_rmdir (state_file);
-	g_free (state_file);
-
-	g_rmdir (folder_dir);
-	g_free (folder_dir);
-
- event:
-
-	camel_store_summary_remove_path ((CamelStoreSummary *)imap_store->summary, folder_name);
-	camel_store_summary_save ((CamelStoreSummary *)imap_store->summary);
-
-	fi = imap_build_folder_info (imap_store, folder_name);
-	camel_store_folder_deleted (CAMEL_STORE (imap_store), fi);
-	camel_folder_info_free (fi);
-}
-
-static gboolean
-imap_check_folder_still_extant (CamelImapStore *imap_store, const gchar *full_name,
-				GError **error)
-{
-	CamelImapResponse *response;
-
-	response = camel_imap_command (imap_store, NULL, NULL, "LIST \"\" %F",
-				       full_name);
-
-	if (response) {
-		gboolean stillthere = response->untagged->len != 0;
-
-		camel_imap_response_free_without_processing (imap_store, response);
-
-		return stillthere;
-	}
-
-	/* if the command was rejected, there must be some other error,
-	   assume it worked so we dont blow away the folder unecessarily */
-	return TRUE;
+	return connect_to_server (
+		service, service->url->host, serv,
+		fallback_port, mode, cancellable, error);
 }
 
 static gboolean
-try_auth (CamelImapStore *store, const gchar *mech, GError **error)
+try_auth (CamelImapStore *store,
+          const gchar *mech,
+          GCancellable *cancellable,
+          GError **error)
 {
 	CamelSasl *sasl;
 	CamelImapResponse *response;
 	gchar *resp;
 	gchar *sasl_resp;
 
-	response = camel_imap_command (store, NULL, error, "AUTHENTICATE %s", mech);
+	response = camel_imap_command (store, NULL, cancellable, error, "AUTHENTICATE %s", mech);
 	if (!response)
 		return FALSE;
 
@@ -1064,12 +674,13 @@ try_auth (CamelImapStore *store, const gchar *mech, GError **error)
 		if (!resp)
 			goto lose;
 
-		sasl_resp = camel_sasl_challenge_base64 (sasl, imap_next_word (resp), error);
+		sasl_resp = camel_sasl_challenge_base64 (
+			sasl, imap_next_word (resp), cancellable, error);
 		g_free (resp);
 		if (!sasl_resp)
 			goto break_and_lose;
 
-		response = camel_imap_command_continuation (store, sasl_resp, strlen (sasl_resp), error);
+		response = camel_imap_command_continuation (store, sasl_resp, strlen (sasl_resp), cancellable, error);
 		g_free (sasl_resp);
 		if (!response)
 			goto lose;
@@ -1090,7 +701,7 @@ try_auth (CamelImapStore *store, const gchar *mech, GError **error)
 
  break_and_lose:
 	/* Get the server out of "waiting for continuation data" mode. */
-	response = camel_imap_command_continuation (store, "*", 1, NULL);
+	response = camel_imap_command_continuation (store, "*", 1, cancellable, NULL);
 	if (response)
 		camel_imap_response_free (store, response);
 
@@ -1101,7 +712,9 @@ try_auth (CamelImapStore *store, const gchar *mech, GError **error)
 }
 
 static gboolean
-imap_auth_loop (CamelService *service, GError **error)
+imap_auth_loop (CamelService *service,
+                GCancellable *cancellable,
+                GError **error)
 {
 	CamelImapStore *store = CAMEL_IMAP_STORE (service);
 	CamelSession *session = camel_service_get_session (service);
@@ -1144,7 +757,9 @@ imap_auth_loop (CamelService *service, GError **error)
 		}
 
 		if (!authtype->need_password) {
-			authenticated = try_auth (store, authtype->authproto, error);
+			authenticated = try_auth (
+				store, authtype->authproto,
+				cancellable, error);
 			if (!authenticated)
 				return FALSE;
 		}
@@ -1193,14 +808,17 @@ imap_auth_loop (CamelService *service, GError **error)
 		if (!store->connected) {
 			/* Some servers (eg, courier) will disconnect on
 			 * a bad password. So reconnect here. */
-			if (!connect_to_server_wrapper (service, error))
+			if (!connect_to_server_wrapper (
+				service, cancellable, error))
 				return FALSE;
 		}
 
 		if (authtype)
-			authenticated = try_auth (store, authtype->authproto, &local_error);
+			authenticated = try_auth (
+				store, authtype->authproto,
+				cancellable, &local_error);
 		else {
-			response = camel_imap_command (store, NULL, &local_error,
+			response = camel_imap_command (store, NULL, cancellable, &local_error,
 						       "LOGIN %S %S",
 						       service->url->user,
 						       service->url->passwd);
@@ -1227,7 +845,210 @@ imap_auth_loop (CamelService *service, GError **error)
 }
 
 static gboolean
-imap_connect (CamelService *service, GError **error)
+free_key (gpointer key, gpointer value, gpointer user_data)
+{
+	g_free (key);
+	return TRUE;
+}
+
+static void
+imap_store_dispose (GObject *object)
+{
+	CamelImapStore *imap_store = CAMEL_IMAP_STORE (object);
+
+	if (imap_store->summary != NULL) {
+		camel_store_summary_save (
+			CAMEL_STORE_SUMMARY (imap_store->summary));
+		g_object_unref (imap_store->summary);
+		imap_store->summary = NULL;
+	}
+
+	/* Chain up to parent's dispose() method. */
+	G_OBJECT_CLASS (camel_imap_store_parent_class)->dispose (object);
+}
+
+static void
+imap_store_finalize (GObject *object)
+{
+	CamelImapStore *imap_store = CAMEL_IMAP_STORE (object);
+
+	/* This frees current_folder, folders, authtypes, streams, and namespace. */
+	camel_service_disconnect (CAMEL_SERVICE (imap_store), TRUE, NULL);
+
+	g_free (imap_store->base_url);
+	g_free (imap_store->storage_path);
+	g_free (imap_store->users_namespace);
+	g_free (imap_store->custom_headers);
+	g_free (imap_store->real_trash_path);
+	g_free (imap_store->real_junk_path);
+
+	/* Chain up to parent's finalize() method. */
+	G_OBJECT_CLASS (camel_imap_store_parent_class)->finalize (object);
+}
+
+static gboolean
+imap_store_construct (CamelService *service,
+                      CamelSession *session,
+                      CamelProvider *provider,
+                      CamelURL *url,
+                      GError **error)
+{
+	CamelServiceClass *service_class;
+	CamelImapStore *imap_store = CAMEL_IMAP_STORE (service);
+	CamelStore *store = CAMEL_STORE (service);
+	gchar *tmp;
+	CamelURL *summary_url;
+
+	/* Chain up to parent's construct() method. */
+	service_class = CAMEL_SERVICE_CLASS (camel_imap_store_parent_class);
+	if (!service_class->construct (service, session, provider, url, error))
+		return FALSE;
+
+	imap_store->storage_path = camel_session_get_storage_path (session, service, error);
+	if (!imap_store->storage_path)
+		return FALSE;
+
+	/* FIXME */
+	imap_store->base_url = camel_url_to_string (service->url, (CAMEL_URL_HIDE_PASSWORD |
+								   CAMEL_URL_HIDE_PARAMS |
+								   CAMEL_URL_HIDE_AUTH));
+
+	imap_store->parameters = 0;
+	if (camel_url_get_param (url, "use_lsub"))
+		imap_store->parameters |= IMAP_PARAM_SUBSCRIPTIONS;
+	if (camel_url_get_param (url, "override_namespace") && camel_url_get_param (url, "namespace")) {
+		imap_store->parameters |= IMAP_PARAM_OVERRIDE_NAMESPACE;
+		g_free(imap_store->users_namespace);
+		imap_store->users_namespace = g_strdup (camel_url_get_param (url, "namespace"));
+	}
+	if (camel_url_get_param (url, "check_all"))
+		imap_store->parameters |= IMAP_PARAM_CHECK_ALL;
+	if (camel_url_get_param (url, "check_lsub"))
+		imap_store->parameters |= IMAP_PARAM_CHECK_LSUB;
+	if (camel_url_get_param (url, "filter")) {
+		imap_store->parameters |= IMAP_PARAM_FILTER_INBOX;
+		store->flags |= CAMEL_STORE_FILTER_INBOX;
+	}
+	if (camel_url_get_param (url, "filter_junk"))
+		imap_store->parameters |= IMAP_PARAM_FILTER_JUNK;
+	if (camel_url_get_param (url, "filter_junk_inbox"))
+		imap_store->parameters |= IMAP_PARAM_FILTER_JUNK_INBOX;
+
+	imap_store->headers = IMAP_FETCH_MAILING_LIST_HEADERS;
+	if (camel_url_get_param (url, "all_headers"))
+		imap_store->headers = IMAP_FETCH_ALL_HEADERS;
+	else if (camel_url_get_param (url, "basic_headers"))
+		imap_store->headers = IMAP_FETCH_MINIMAL_HEADERS;
+
+	if (camel_url_get_param (url, "imap_custom_headers")) {
+		imap_store->custom_headers = g_strdup(camel_url_get_param (url, "imap_custom_headers"));
+	}
+
+	imap_store->real_trash_path = g_strdup (camel_url_get_param (url, "real_trash_path"));
+	imap_store->real_junk_path = g_strdup (camel_url_get_param (url, "real_junk_path"));
+
+	if (imap_store->real_trash_path && !*imap_store->real_trash_path) {
+		g_free (imap_store->real_trash_path);
+		imap_store->real_trash_path = NULL;
+	}
+
+	if (imap_store->real_trash_path && *imap_store->real_trash_path)
+		store->flags &= ~CAMEL_STORE_VTRASH;
+
+	if (imap_store->real_junk_path && !*imap_store->real_junk_path) {
+		g_free (imap_store->real_junk_path);
+		imap_store->real_junk_path = NULL;
+	}
+
+	if (imap_store->real_junk_path && *imap_store->real_junk_path) {
+		store->flags &= ~CAMEL_STORE_VJUNK;
+		store->flags |= CAMEL_STORE_REAL_JUNK_FOLDER;
+	}
+
+	/* setup/load the store summary */
+	tmp = alloca(strlen(imap_store->storage_path)+32);
+	sprintf(tmp, "%s/.ev-store-summary", imap_store->storage_path);
+	imap_store->summary = camel_imap_store_summary_new();
+	camel_store_summary_set_filename((CamelStoreSummary *)imap_store->summary, tmp);
+	summary_url = camel_url_new(imap_store->base_url, NULL);
+	camel_store_summary_set_uri_base((CamelStoreSummary *)imap_store->summary, summary_url);
+	camel_url_free(summary_url);
+	if (camel_store_summary_load((CamelStoreSummary *)imap_store->summary) == 0) {
+		CamelImapStoreSummary *is = imap_store->summary;
+
+		if (is->namespace) {
+			/* if namespace has changed, clear folder list */
+			if (imap_store->users_namespace && strcmp(imap_store->users_namespace, is->namespace->full_name) != 0) {
+				camel_store_summary_clear((CamelStoreSummary *)is);
+			}
+		}
+
+		imap_store->capabilities = is->capabilities;
+		imap_set_server_level(imap_store);
+	}
+
+	return TRUE;
+}
+
+static GList *
+imap_store_query_auth_types (CamelService *service,
+                             GCancellable *cancellable,
+                             GError **error)
+{
+	CamelImapStore *store = CAMEL_IMAP_STORE (service);
+	CamelServiceAuthType *authtype;
+	GList *sasl_types, *t, *next;
+	gboolean connected;
+
+	if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
+		g_set_error (
+			error, CAMEL_SERVICE_ERROR,
+			CAMEL_SERVICE_ERROR_UNAVAILABLE,
+			_("You must be working online to complete this operation"));
+		return NULL;
+	}
+
+	camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+	connected = store->istream != NULL && store->connected;
+	if (!connected)
+		connected = connect_to_server_wrapper (
+			service, cancellable, error);
+	camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+	if (!connected)
+		return NULL;
+
+	sasl_types = camel_sasl_authtype_list (FALSE);
+	for (t = sasl_types; t; t = next) {
+		authtype = t->data;
+		next = t->next;
+
+		if (!g_hash_table_lookup (store->authtypes, authtype->authproto)) {
+			sasl_types = g_list_remove_link (sasl_types, t);
+			g_list_free_1 (t);
+		}
+	}
+
+	return g_list_prepend (sasl_types, &camel_imap_password_authtype);
+}
+
+static gchar *
+imap_store_get_name (CamelService *service,
+                     gboolean brief)
+{
+	if (brief)
+		return g_strdup_printf (
+			_("IMAP server %s"),
+			service->url->host);
+	else
+		return g_strdup_printf (
+			_("IMAP service for %s on %s"),
+			service->url->user, service->url->host);
+}
+
+static gboolean
+imap_store_connect (CamelService *service,
+                    GCancellable *cancellable,
+                    GError **error)
 {
 	CamelImapStore *store = CAMEL_IMAP_STORE (service);
 	CamelImapResponse *response;
@@ -1239,8 +1060,8 @@ imap_connect (CamelService *service, GError **error)
 		return TRUE;
 
 	camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-	if (!connect_to_server_wrapper (service, error) ||
-	    !imap_auth_loop (service, error)) {
+	if (!connect_to_server_wrapper (service, cancellable, error) ||
+	    !imap_auth_loop (service, cancellable, error)) {
 		camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 		camel_service_disconnect (service, TRUE, NULL);
 		return FALSE;
@@ -1250,7 +1071,7 @@ imap_connect (CamelService *service, GError **error)
 	if (store->capabilities & IMAP_CAPABILITY_NAMESPACE) {
 		struct _namespaces *namespaces;
 
-		response = camel_imap_command (store, NULL, &local_error, "NAMESPACE");
+		response = camel_imap_command (store, NULL, cancellable, &local_error, "NAMESPACE");
 		if (!response)
 			goto done;
 
@@ -1334,7 +1155,7 @@ imap_connect (CamelService *service, GError **error)
 			/* This idiom means "tell me the hierarchy separator
 			 * for the given path, even if that path doesn't exist.
 			 */
-			response = camel_imap_command (store, NULL, &local_error,
+			response = camel_imap_command (store, NULL, cancellable, &local_error,
 						       "LIST %G \"\"",
 						       use_namespace);
 		} else {
@@ -1342,7 +1163,7 @@ imap_connect (CamelService *service, GError **error)
 			 * to "tell me about this folder", which will fail if
 			 * the folder doesn't exist (eg, if namespace is "").
 			 */
-			response = camel_imap_command (store, NULL, &local_error,
+			response = camel_imap_command (store, NULL, cancellable, &local_error,
 						       "LIST \"\" %G",
 						       use_namespace);
 		}
@@ -1372,13 +1193,13 @@ imap_connect (CamelService *service, GError **error)
 		CamelStoreInfo *si;
 
 		/* look in all namespaces */
-		if (!get_folders_sync (store, NULL, &local_error))
+		if (!get_folders_sync (store, NULL, cancellable, &local_error))
 			goto done;
 
 		/* Make sure INBOX is present/subscribed */
 		si = camel_store_summary_path((CamelStoreSummary *)store->summary, "INBOX");
 		if (si == NULL || (si->flags & CAMEL_FOLDER_SUBSCRIBED) == 0) {
-			response = camel_imap_command (store, NULL, &local_error, "SUBSCRIBE INBOX");
+			response = camel_imap_command (store, NULL, cancellable, &local_error, "SUBSCRIBE INBOX");
 			if (response != NULL) {
 				camel_imap_response_free (store, response);
 			}
@@ -1386,7 +1207,7 @@ imap_connect (CamelService *service, GError **error)
 				camel_store_summary_info_free ((CamelStoreSummary *)store->summary, si);
 			if (local_error != NULL)
 				goto done;
-			get_folders_sync(store, "INBOX", &local_error);
+			get_folders_sync(store, "INBOX", cancellable, &local_error);
 		}
 
 		store->refresh_stamp = time (NULL);
@@ -1408,25 +1229,28 @@ done:
 }
 
 static gboolean
-imap_disconnect (CamelService *service, gboolean clean, GError **error)
+imap_store_disconnect (CamelService *service,
+                       gboolean clean,
+                       GCancellable *cancellable,
+                       GError **error)
 {
 	CamelImapStore *store = CAMEL_IMAP_STORE (service);
 
 	if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_AVAIL && clean) {
 		CamelImapResponse *response;
 
-		response = camel_imap_command (store, NULL, NULL, "LOGOUT");
+		response = camel_imap_command (store, NULL, NULL, NULL, "LOGOUT");
 		camel_imap_response_free (store, response);
 	}
 
 	if (store->istream) {
-		camel_stream_close (store->istream, NULL);
+		camel_stream_close (store->istream, cancellable, NULL);
 		g_object_unref (store->istream);
 		store->istream = NULL;
 	}
 
 	if (store->ostream) {
-		camel_stream_close (store->ostream, NULL);
+		camel_stream_close (store->ostream, cancellable, NULL);
 		g_object_unref (store->ostream);
 		store->ostream = NULL;
 	}
@@ -1452,6 +1276,219 @@ imap_disconnect (CamelService *service, gboolean clean, GError **error)
 	return TRUE;
 }
 
+static void
+camel_imap_store_class_init (CamelImapStoreClass *class)
+{
+	GObjectClass *object_class;
+	CamelServiceClass *service_class;
+	CamelStoreClass *store_class;
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->dispose = imap_store_dispose;
+	object_class->finalize = imap_store_finalize;
+
+	service_class = CAMEL_SERVICE_CLASS (class);
+	service_class->construct = imap_store_construct;
+	service_class->query_auth_types = imap_store_query_auth_types;
+	service_class->get_name = imap_store_get_name;
+	service_class->connect = imap_store_connect;
+	service_class->disconnect = imap_store_disconnect;
+
+	store_class = CAMEL_STORE_CLASS (class);
+	store_class->hash_folder_name = hash_folder_name;
+	store_class->compare_folder_name = compare_folder_name;
+	store_class->get_folder = get_folder;
+	store_class->create_folder = create_folder;
+	store_class->delete_folder = delete_folder;
+	store_class->rename_folder = rename_folder;
+	store_class->get_folder_info = get_folder_info;
+	store_class->free_folder_info = camel_store_free_folder_info_full;
+	store_class->folder_is_subscribed = folder_is_subscribed;
+	store_class->subscribe_folder = subscribe_folder;
+	store_class->unsubscribe_folder = unsubscribe_folder;
+	store_class->noop = imap_noop;
+	store_class->get_trash = imap_get_trash;
+	store_class->get_junk = imap_get_junk;
+	store_class->can_refresh_folder = imap_can_refresh_folder;
+}
+
+static void
+camel_imap_store_init (CamelImapStore *imap_store)
+{
+	imap_store->istream = NULL;
+	imap_store->ostream = NULL;
+
+	/* TODO: support dir_sep per namespace */
+	imap_store->dir_sep = '\0';
+	imap_store->current_folder = NULL;
+	imap_store->connected = FALSE;
+	imap_store->preauthed = FALSE;
+	((CamelStore *)imap_store)->flags |= CAMEL_STORE_SUBSCRIPTIONS;
+
+	imap_store->tag_prefix = imap_tag_prefix++;
+	if (imap_tag_prefix > 'Z')
+		imap_tag_prefix = 'A';
+}
+
+static void
+imap_set_server_level (CamelImapStore *store)
+{
+	if (store->capabilities & IMAP_CAPABILITY_IMAP4REV1) {
+		store->server_level = IMAP_LEVEL_IMAP4REV1;
+		store->capabilities |= IMAP_CAPABILITY_STATUS;
+	} else if (store->capabilities & IMAP_CAPABILITY_IMAP4)
+		store->server_level = IMAP_LEVEL_IMAP4;
+	else
+		store->server_level = IMAP_LEVEL_UNKNOWN;
+}
+
+/* folder_name is path name */
+static CamelFolderInfo *
+imap_build_folder_info(CamelImapStore *imap_store, const gchar *folder_name)
+{
+	CamelURL *url;
+	const gchar *name;
+	CamelFolderInfo *fi;
+
+	fi = camel_folder_info_new ();
+	fi->full_name = g_strdup(folder_name);
+	fi->unread = -1;
+	fi->total = -1;
+
+	url = camel_url_new (imap_store->base_url, NULL);
+	g_free (url->path);
+	url->path = g_strdup_printf ("/%s", folder_name);
+	fi->uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
+	camel_url_free(url);
+	name = strrchr (fi->full_name, '/');
+	if (name == NULL)
+		name = fi->full_name;
+	else
+		name++;
+	if (!g_ascii_strcasecmp (fi->full_name, "INBOX"))
+		fi->name = g_strdup (_("Inbox"));
+	/* Do not localize the rest, these are from a server, thus shouldn't be localized */
+	/*else if (!g_ascii_strcasecmp (fi->full_name, "Drafts"))
+		fi->name = g_strdup (_("Drafts"));
+	else if (!g_ascii_strcasecmp (fi->full_name, "Sent"))
+		fi->name = g_strdup (_("Sent"));
+	else if (!g_ascii_strcasecmp (fi->full_name, "Templates"))
+		fi->name = g_strdup (_("Templates"));
+	else if (!g_ascii_strcasecmp (fi->full_name, "Trash"))
+		fi->name = g_strdup (_("Trash"));*/
+	else
+		fi->name = g_strdup (name);
+
+	return fi;
+}
+
+static gboolean
+imap_folder_effectively_unsubscribed (CamelImapStore *imap_store,
+                                      const gchar *folder_name,
+                                      GError **error)
+{
+	CamelFolderInfo *fi;
+	CamelStoreInfo *si;
+
+	si = camel_store_summary_path((CamelStoreSummary *)imap_store->summary, folder_name);
+	if (si) {
+		if (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) {
+			si->flags &= ~CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
+			camel_store_summary_touch((CamelStoreSummary *)imap_store->summary);
+			camel_store_summary_save((CamelStoreSummary *)imap_store->summary);
+		}
+		camel_store_summary_info_free((CamelStoreSummary *)imap_store->summary, si);
+	}
+
+	if (imap_store->renaming) {
+		/* we don't need to emit a "folder_unsubscribed" signal
+                   if we are in the process of renaming folders, so we
+                   are done here... */
+		return TRUE;
+
+	}
+
+	fi = imap_build_folder_info(imap_store, folder_name);
+	camel_store_folder_unsubscribed (CAMEL_STORE (imap_store), fi);
+	camel_folder_info_free (fi);
+
+	return TRUE;
+}
+
+static void
+imap_forget_folder (CamelImapStore *imap_store, const gchar *folder_name, GError **error)
+{
+	gchar *state_file;
+	gchar *journal_file;
+	gchar *folder_dir, *storage_path;
+	CamelFolderInfo *fi;
+	const gchar *name;
+
+	name = strrchr (folder_name, imap_store->dir_sep);
+	if (name)
+		name++;
+	else
+		name = folder_name;
+
+	storage_path = g_strdup_printf ("%s/folders", imap_store->storage_path);
+	folder_dir = imap_path_to_physical (storage_path, folder_name);
+	g_free (storage_path);
+	if (g_access (folder_dir, F_OK) != 0) {
+		g_free (folder_dir);
+		goto event;
+	}
+
+	/* Delete summary and all the data */
+	journal_file = g_strdup_printf ("%s/journal", folder_dir);
+	g_unlink (journal_file);
+	g_free (journal_file);
+
+	state_file = g_strdup_printf ("%s/cmeta", folder_dir);
+	g_unlink (state_file);
+	g_free (state_file);
+
+	camel_db_delete_folder (((CamelStore *)imap_store)->cdb_w, folder_name, NULL);
+	camel_imap_message_cache_delete (folder_dir, NULL);
+
+	state_file = g_strdup_printf("%s/subfolders", folder_dir);
+	g_rmdir(state_file);
+	g_free(state_file);
+
+	g_rmdir (folder_dir);
+	g_free (folder_dir);
+
+ event:
+
+	camel_store_summary_remove_path((CamelStoreSummary *)imap_store->summary, folder_name);
+	camel_store_summary_save((CamelStoreSummary *)imap_store->summary);
+
+	fi = imap_build_folder_info(imap_store, folder_name);
+	camel_store_folder_deleted (CAMEL_STORE (imap_store), fi);
+	camel_folder_info_free (fi);
+}
+
+static gboolean
+imap_check_folder_still_extant (CamelImapStore *imap_store, const gchar *full_name,
+				GError **error)
+{
+	CamelImapResponse *response;
+
+	response = camel_imap_command (imap_store, NULL, NULL, NULL, "LIST \"\" %F",
+				       full_name);
+
+	if (response) {
+		gboolean stillthere = response->untagged->len != 0;
+
+		camel_imap_response_free_without_processing (imap_store, response);
+
+		return stillthere;
+	}
+
+	/* if the command was rejected, there must be some other error,
+	   assume it worked so we dont blow away the folder unecessarily */
+	return TRUE;
+}
+
 static gboolean
 imap_summary_is_dirty (CamelFolderSummary *summary)
 {
@@ -1473,6 +1510,7 @@ imap_summary_is_dirty (CamelFolderSummary *summary)
 
 static gboolean
 imap_noop (CamelStore *store,
+           GCancellable *cancellable,
            GError **error)
 {
 	CamelImapStore *imap_store = (CamelImapStore *) store;
@@ -1490,9 +1528,10 @@ imap_noop (CamelStore *store,
 	current_folder = imap_store->current_folder;
 	if (current_folder && imap_summary_is_dirty (current_folder->summary)) {
 		/* let's sync the flags instead.  NB: must avoid folder lock */
-		success = CAMEL_FOLDER_GET_CLASS (current_folder)->sync (current_folder, FALSE, error);
+		success = CAMEL_FOLDER_GET_CLASS (current_folder)->sync (
+			current_folder, FALSE, cancellable, error);
 	} else {
-		response = camel_imap_command (imap_store, NULL, error, "NOOP");
+		response = camel_imap_command (imap_store, NULL, cancellable, error, "NOOP");
 		if (response)
 			camel_imap_response_free (imap_store, response);
 		else
@@ -1505,13 +1544,17 @@ done:
 }
 
 static CamelFolder *
-imap_get_trash (CamelStore *store, GError **error)
+imap_get_trash (CamelStore *store,
+                GCancellable *cancellable,
+                GError **error)
 {
 	CamelFolder *folder = NULL;
 	CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
 
 	if (imap_store->real_trash_path && *imap_store->real_trash_path) {
-		folder = camel_store_get_folder (store, imap_store->real_trash_path, 0, NULL);
+		folder = camel_store_get_folder (
+			store, imap_store->real_trash_path, 0,
+			cancellable, NULL);
 		if (!folder) {
 			/* cannot find configured folder, just report on console and unset in a store structure to not try again */
 			g_free (imap_store->real_trash_path);
@@ -1522,7 +1565,8 @@ imap_get_trash (CamelStore *store, GError **error)
 	if (folder)
 		return folder;
 
-	folder = CAMEL_STORE_CLASS (camel_imap_store_parent_class)->get_trash (store, error);
+	folder = CAMEL_STORE_CLASS (camel_imap_store_parent_class)->
+		get_trash (store, cancellable, error);
 
 	if (folder) {
 		CamelObject *object = CAMEL_OBJECT (folder);
@@ -1538,13 +1582,17 @@ imap_get_trash (CamelStore *store, GError **error)
 }
 
 static CamelFolder *
-imap_get_junk (CamelStore *store, GError **error)
+imap_get_junk (CamelStore *store,
+               GCancellable *cancellable,
+               GError **error)
 {
 	CamelFolder *folder = NULL;
 	CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
 
 	if (imap_store->real_junk_path && *imap_store->real_junk_path) {
-		folder = camel_store_get_folder (store, imap_store->real_junk_path, 0, NULL);
+		folder = camel_store_get_folder (
+			store, imap_store->real_junk_path, 0,
+			cancellable, NULL);
 		if (!folder) {
 			/* cannot find configured folder, just report on console and unset in a store structure to not try again */
 			g_free (imap_store->real_junk_path);
@@ -1555,7 +1603,8 @@ imap_get_junk (CamelStore *store, GError **error)
 	if (folder)
 		return folder;
 
-	folder = CAMEL_STORE_CLASS (camel_imap_store_parent_class)->get_junk (store, error);
+	folder = CAMEL_STORE_CLASS (camel_imap_store_parent_class)->
+		get_junk (store, cancellable, error);
 
 	if (folder) {
 		CamelObject *object = CAMEL_OBJECT (folder);
@@ -1619,7 +1668,7 @@ get_folder_status (CamelImapStore *imap_store, const gchar *folder_name, const g
 
 	/* FIXME: we assume the server is STATUS-capable */
 
-	response = camel_imap_command (imap_store, NULL, NULL,
+	response = camel_imap_command (imap_store, NULL, NULL, NULL,
 				       "STATUS %F (%s)",
 				       folder_name,
 				       type);
@@ -1697,7 +1746,11 @@ get_folder_status (CamelImapStore *imap_store, const gchar *folder_name, const g
 }
 
 static CamelFolder *
-get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError **error)
+get_folder (CamelStore *store,
+            const gchar *folder_name,
+            guint32 flags,
+            GCancellable *cancellable,
+            GError **error)
 {
 	CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
 	CamelImapResponse *response;
@@ -1736,7 +1789,7 @@ get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError *
 		imap_store->current_folder = NULL;
 	}
 
-	response = camel_imap_command (imap_store, NULL, &local_error, "SELECT %F", folder_name);
+	response = camel_imap_command (imap_store, NULL, cancellable, &local_error, "SELECT %F", folder_name);
 	if (!response) {
 		gchar *folder_real, *parent_name, *parent_real;
 		const gchar *c;
@@ -1786,7 +1839,7 @@ get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError *
 			gint flags;
 			gint i;
 
-			if (!(response = camel_imap_command (imap_store, NULL, error, "LIST \"\" %G", parent_real))) {
+			if (!(response = camel_imap_command (imap_store, NULL, cancellable, error, "LIST \"\" %G", parent_real))) {
 				camel_service_unlock (CAMEL_SERVICE (imap_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 				g_free (parent_name);
 				g_free (parent_real);
@@ -1840,7 +1893,8 @@ get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError *
 				}
 
 				/* delete the old parent and recreate it */
-				if (!delete_folder (store, parent_name, error)) {
+				if (!delete_folder (
+					store, parent_name, cancellable, error)) {
 					camel_service_unlock (CAMEL_SERVICE (imap_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 					g_free (parent_name);
 					g_free (parent_real);
@@ -1849,7 +1903,7 @@ get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError *
 
 				/* add the dirsep to the end of parent_name */
 				name = g_strdup_printf ("%s%c", parent_real, imap_store->dir_sep);
-				response = camel_imap_command (imap_store, NULL, error, "CREATE %G",
+				response = camel_imap_command (imap_store, NULL, cancellable, error, "CREATE %G",
 							       name);
 				g_free (name);
 
@@ -1868,13 +1922,13 @@ get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError *
 		g_free (parent_name);
 
 		folder_real = camel_imap_store_summary_path_to_full (imap_store->summary, folder_name, imap_store->dir_sep);
-		response = camel_imap_command (imap_store, NULL, error, "CREATE %G", folder_real);
+		response = camel_imap_command (imap_store, NULL, cancellable, error, "CREATE %G", folder_real);
 		if (response) {
 			camel_imap_store_summary_add_from_full (imap_store->summary, folder_real, imap_store->dir_sep);
 
 			camel_imap_response_free (imap_store, response);
 
-			response = camel_imap_command (imap_store, NULL, NULL, "SELECT %F", folder_name);
+			response = camel_imap_command (imap_store, NULL, NULL, NULL, "SELECT %F", folder_name);
 		}
 		g_free (folder_real);
 		if (!response) {
@@ -1901,7 +1955,8 @@ get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError *
 	g_free (folder_dir);
 	if (new_folder) {
 		imap_store->current_folder = g_object_ref (new_folder);
-		if (!camel_imap_folder_selected (new_folder, response, error)) {
+		if (!camel_imap_folder_selected (
+			new_folder, response, cancellable, error)) {
 
 			g_object_unref (imap_store->current_folder);
 			imap_store->current_folder = NULL;
@@ -1958,6 +2013,7 @@ get_folder_offline (CamelStore *store, const gchar *folder_name,
 static gboolean
 delete_folder (CamelStore *store,
                const gchar *folder_name,
+               GCancellable *cancellable,
                GError **error)
 {
 	CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
@@ -1972,7 +2028,7 @@ delete_folder (CamelStore *store,
 	}
 
 	/* make sure this folder isn't currently SELECTed */
-	response = camel_imap_command (imap_store, NULL, error, "SELECT INBOX");
+	response = camel_imap_command (imap_store, NULL, cancellable, error, "SELECT INBOX");
 	if (!response) {
 		success = FALSE;
 		goto fail;
@@ -1984,7 +2040,7 @@ delete_folder (CamelStore *store,
 	/* no need to actually create a CamelFolder for INBOX */
 	imap_store->current_folder = NULL;
 
-	response = camel_imap_command(imap_store, NULL, error, "DELETE %F", folder_name);
+	response = camel_imap_command(imap_store, NULL, cancellable, error, "DELETE %F", folder_name);
 	if (response) {
 		camel_imap_response_free (imap_store, response);
 		imap_forget_folder (imap_store, folder_name, NULL);
@@ -1998,7 +2054,10 @@ fail:
 }
 
 static void
-manage_subscriptions (CamelStore *store, const gchar *old_name, gboolean subscribe)
+manage_subscriptions (CamelStore *store,
+                      const gchar *old_name,
+                      gboolean subscribe,
+                      GCancellable *cancellable)
 {
 	CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
 	CamelStoreInfo *si;
@@ -2013,9 +2072,11 @@ manage_subscriptions (CamelStore *store, const gchar *old_name, gboolean subscri
 			path = camel_store_info_path (imap_store->summary, si);
 			if (strncmp (path, old_name, olen) == 0) {
 				if (subscribe)
-					subscribe_folder (store, path, NULL);
+					subscribe_folder (
+						store, path, cancellable, NULL);
 				else
-					unsubscribe_folder (store, path, NULL);
+					unsubscribe_folder (
+						store, path, cancellable, NULL);
 			}
 			camel_store_summary_info_free ((CamelStoreSummary *)imap_store->summary, si);
 		}
@@ -2049,7 +2110,7 @@ rename_folder_info (CamelImapStore *imap_store, const gchar *old_name, const gch
 			if (imap_store->dir_sep == '.') {
 				CamelImapResponse *response;
 
-				response = camel_imap_command (imap_store, NULL, NULL, "RENAME %F %G", path, nfull);
+				response = camel_imap_command (imap_store, NULL, NULL, NULL, "RENAME %F %G", path, nfull);
 				if (response)
 					camel_imap_response_free (imap_store, response);
 			}
@@ -2069,6 +2130,7 @@ static gboolean
 rename_folder (CamelStore *store,
                const gchar *old_name,
                const gchar *new_name_in,
+               GCancellable *cancellable,
                GError **error)
 {
 	CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
@@ -2086,7 +2148,7 @@ rename_folder (CamelStore *store,
 	/* make sure this folder isn't currently SELECTed - it's
            actually possible to rename INBOX but if you do another
            INBOX will immediately be created by the server */
-	response = camel_imap_command (imap_store, NULL, error, "SELECT INBOX");
+	response = camel_imap_command (imap_store, NULL, cancellable, error, "SELECT INBOX");
 	if (!response) {
 		success = FALSE;
 		goto fail;
@@ -2100,12 +2162,14 @@ rename_folder (CamelStore *store,
 
 	imap_store->renaming = TRUE;
 	if (imap_store->parameters & IMAP_PARAM_SUBSCRIPTIONS)
-		manage_subscriptions (store, old_name, FALSE);
+		manage_subscriptions (
+			store, old_name, FALSE, cancellable);
 
-	response = camel_imap_command (imap_store, NULL, error, "RENAME %F %F", old_name, new_name_in);
+	response = camel_imap_command (imap_store, NULL, cancellable, error, "RENAME %F %F", old_name, new_name_in);
 	if (!response) {
 		if (imap_store->parameters & IMAP_PARAM_SUBSCRIPTIONS)
-			manage_subscriptions (store, old_name, TRUE);
+			manage_subscriptions (
+				store, old_name, TRUE, cancellable);
 		success = FALSE;
 		goto fail;
 	}
@@ -2116,7 +2180,8 @@ rename_folder (CamelStore *store,
 	rename_folder_info (imap_store, old_name, new_name_in);
 
 	if (imap_store->parameters & IMAP_PARAM_SUBSCRIPTIONS)
-		manage_subscriptions (store, new_name_in, TRUE);
+		manage_subscriptions (
+			store, new_name_in, TRUE, cancellable);
 
 	storage_path = g_strdup_printf("%s/folders", imap_store->storage_path);
 	oldpath = imap_path_to_physical (storage_path, old_name);
@@ -2160,8 +2225,11 @@ fail:
 }
 
 static CamelFolderInfo *
-create_folder (CamelStore *store, const gchar *parent_name,
-	       const gchar *folder_name, GError **error)
+create_folder (CamelStore *store,
+               const gchar *parent_name,
+               const gchar *folder_name,
+               GCancellable *cancellable,
+               GError **error)
 {
 	CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
 	gchar *full_name, *resp, *thisone, *parent_real, *real_name;
@@ -2208,7 +2276,7 @@ create_folder (CamelStore *store, const gchar *parent_name,
 	}
 
 	need_convert = FALSE;
-	response = camel_imap_command (imap_store, NULL, error, "LIST \"\" %G",
+	response = camel_imap_command (imap_store, NULL, cancellable, error, "LIST \"\" %G",
 				       parent_real);
 	if (!response) /* whoa, this is bad */ {
 		g_free (parent_real);
@@ -2260,12 +2328,12 @@ create_folder (CamelStore *store, const gchar *parent_name,
 		}
 
 		/* delete the old parent and recreate it */
-		if (!delete_folder (store, parent_name, error))
+		if (!delete_folder (store, parent_name, cancellable, error))
 			return NULL;
 
 		/* add the dirsep to the end of parent_name */
 		name = g_strdup_printf ("%s%c", parent_real, imap_store->dir_sep);
-		response = camel_imap_command (imap_store, NULL, error, "CREATE %G",
+		response = camel_imap_command (imap_store, NULL, cancellable, error, "CREATE %G",
 					       name);
 		g_free (name);
 
@@ -2282,7 +2350,7 @@ create_folder (CamelStore *store, const gchar *parent_name,
 	real_name = camel_imap_store_summary_path_to_full (imap_store->summary, folder_name, imap_store->dir_sep);
 	full_name = imap_concat (imap_store, parent_real, real_name);
 	g_free (real_name);
-	response = camel_imap_command (imap_store, NULL, error, "CREATE %G", full_name);
+	response = camel_imap_command (imap_store, NULL, cancellable, error, "CREATE %G", full_name);
 
 	if (response) {
 		CamelImapStoreInfo *si;
@@ -2438,7 +2506,10 @@ get_folders_free (gpointer k, gpointer v, gpointer d)
 }
 
 static gboolean
-get_folders_sync (CamelImapStore *imap_store, const gchar *ppattern, GError **error)
+get_folders_sync (CamelImapStore *imap_store,
+                  const gchar *ppattern,
+                  GCancellable *cancellable,
+                  GError **error)
 {
 	CamelImapResponse *response;
 	CamelFolderInfo *fi, *hfi;
@@ -2474,7 +2545,7 @@ get_folders_sync (CamelImapStore *imap_store, const gchar *ppattern, GError **er
 			}
 
 			for (j = 0; j < 2; j++) {
-				response = camel_imap_command (imap_store, NULL, error,
+				response = camel_imap_command (imap_store, NULL, cancellable, error,
 								"%s \"\" %G", j==1 ? "LSUB" : "LIST",
 								pattern);
 				if (!response) {
@@ -2634,14 +2705,14 @@ refresh_refresh (CamelSession *session, CamelSessionThreadMsg *msg)
 		goto done;
 
 	if (store->users_namespace && store->users_namespace[0]) {
-		if (!get_folders_sync (store, "INBOX", &m->error))
+		if (!get_folders_sync (store, "INBOX", NULL, &m->error))
 			goto done;
 	} else {
-		get_folders_sync (store, "*", NULL);
+		get_folders_sync (store, "*", NULL, NULL);
 	}
 
 	/* look in all namespaces */
-	get_folders_sync (store, NULL, &m->error);
+	get_folders_sync (store, NULL, NULL, &m->error);
 	camel_store_summary_save ((CamelStoreSummary *)store->summary);
 done:
 	camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
@@ -2665,6 +2736,7 @@ static CamelFolderInfo *
 get_folder_info (CamelStore *store,
                  const gchar *top,
                  guint32 flags,
+                 GCancellable *cancellable,
                  GError **error)
 {
 	CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
@@ -2736,13 +2808,13 @@ get_folder_info (CamelStore *store,
 		}
 
 		ns = camel_imap_store_summary_get_main_namespace (imap_store->summary);
-		if (!get_folders_sync (imap_store, pattern, error))
+		if (!get_folders_sync (imap_store, pattern, cancellable, error))
 			goto fail;
 		if (pattern[0] != '*' && ns) {
 			pattern[i] = ns->sep;
 			pattern[i+1] = (flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE)?'*':'%';
 			pattern[i+2] = 0;
-			get_folders_sync (imap_store, pattern, NULL);
+			get_folders_sync (imap_store, pattern, cancellable, NULL);
 		}
 		camel_store_summary_save ((CamelStoreSummary *)imap_store->summary);
 		camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
@@ -2893,6 +2965,7 @@ folder_is_subscribed (CamelStore *store,
 static gboolean
 subscribe_folder (CamelStore *store,
                   const gchar *folder_name,
+                  GCancellable *cancellable,
                   GError **error)
 {
 	CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
@@ -2908,7 +2981,7 @@ subscribe_folder (CamelStore *store,
 		goto done;
 	}
 
-	response = camel_imap_command (imap_store, NULL, error,
+	response = camel_imap_command (imap_store, NULL, cancellable, error,
 				       "SUBSCRIBE %F", folder_name);
 	if (!response) {
 		success = FALSE;
@@ -2948,6 +3021,7 @@ done:
 static gboolean
 unsubscribe_folder (CamelStore *store,
                     const gchar *folder_name,
+                    GCancellable *cancellable,
                     GError **error)
 {
 	CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
@@ -2961,7 +3035,7 @@ unsubscribe_folder (CamelStore *store,
 		goto done;
 	}
 
-	response = camel_imap_command (imap_store, NULL, error,
+	response = camel_imap_command (imap_store, NULL, cancellable, error,
 				       "UNSUBSCRIBE %F", folder_name);
 	if (!response) {
 		success = FALSE;
@@ -3025,7 +3099,10 @@ camel_imap_store_connected (CamelImapStore *store, GError **error)
 }
 
 gssize
-camel_imap_store_readline (CamelImapStore *store, gchar **dest, GError **error)
+camel_imap_store_readline (CamelImapStore *store,
+                           gchar **dest,
+                           GCancellable *cancellable,
+                           GError **error)
 {
 	CamelStreamBuffer *stream;
 	gchar linebuf[1024] = {0};
@@ -3048,7 +3125,7 @@ camel_imap_store_readline (CamelImapStore *store, gchar **dest, GError **error)
 	stream = CAMEL_STREAM_BUFFER (store->istream);
 
 	ba = g_byte_array_new ();
-	while ((nread = camel_stream_buffer_gets (stream, linebuf, sizeof (linebuf), error)) > 0) {
+	while ((nread = camel_stream_buffer_gets (stream, linebuf, sizeof (linebuf), cancellable, error)) > 0) {
 		g_byte_array_append (ba, (const guint8 *) linebuf, nread);
 		if (linebuf[nread - 1] == '\n')
 			break;
diff --git a/camel/providers/imap/camel-imap-store.h b/camel/providers/imap/camel-imap-store.h
index 8e38fe3..dffaa1c 100644
--- a/camel/providers/imap/camel-imap-store.h
+++ b/camel/providers/imap/camel-imap-store.h
@@ -172,7 +172,7 @@ GType camel_imap_store_get_type (void);
 
 gboolean camel_imap_store_connected (CamelImapStore *store, GError **error);
 
-gssize camel_imap_store_readline (CamelImapStore *store, gchar **dest, GError **error);
+gssize camel_imap_store_readline (CamelImapStore *store, gchar **dest, GCancellable *cancellable, GError **error);
 
 G_END_DECLS
 
diff --git a/camel/providers/imap/camel-imap-summary.c b/camel/providers/imap/camel-imap-summary.c
index e7a1b77..f648740 100644
--- a/camel/providers/imap/camel-imap-summary.c
+++ b/camel/providers/imap/camel-imap-summary.c
@@ -384,16 +384,19 @@ content_info_to_db (CamelFolderSummary *s, CamelMessageContentInfo *info, CamelM
 }
 
 void
-camel_imap_summary_add_offline (CamelFolderSummary *summary, const gchar *uid,
-				CamelMimeMessage *message,
-				const CamelMessageInfo *info)
+camel_imap_summary_add_offline (CamelFolderSummary *summary,
+                                const gchar *uid,
+                                CamelMimeMessage *message,
+                                const CamelMessageInfo *info)
 {
 	CamelImapMessageInfo *mi;
 	const CamelFlag *flag;
 	const CamelTag *tag;
 
 	/* Create summary entry */
-	mi = (CamelImapMessageInfo *)camel_folder_summary_info_new_from_message (summary, message, NULL);
+	mi = (CamelImapMessageInfo *)
+		camel_folder_summary_info_new_from_message (
+		summary, message, NULL);
 
 	/* Copy flags 'n' tags */
 	mi->info.flags = camel_message_info_flags (info);
@@ -416,8 +419,9 @@ camel_imap_summary_add_offline (CamelFolderSummary *summary, const gchar *uid,
 }
 
 void
-camel_imap_summary_add_offline_uncached (CamelFolderSummary *summary, const gchar *uid,
-					 const CamelMessageInfo *info)
+camel_imap_summary_add_offline_uncached (CamelFolderSummary *summary,
+                                         const gchar *uid,
+                                         const CamelMessageInfo *info)
 {
 	CamelImapMessageInfo *mi;
 
diff --git a/camel/providers/imap/camel-imap-summary.h b/camel/providers/imap/camel-imap-summary.h
index d7eefb1..1f01238 100644
--- a/camel/providers/imap/camel-imap-summary.h
+++ b/camel/providers/imap/camel-imap-summary.h
@@ -82,17 +82,18 @@ struct _CamelImapSummaryClass {
 
 };
 
-GType               camel_imap_summary_get_type     (void);
-CamelFolderSummary *camel_imap_summary_new          (struct _CamelFolder *folder, const gchar *filename);
-
-void camel_imap_summary_add_offline (CamelFolderSummary *summary,
-				     const gchar *uid,
-				     CamelMimeMessage *message,
-				     const CamelMessageInfo *info);
-
-void camel_imap_summary_add_offline_uncached (CamelFolderSummary *summary,
-					      const gchar *uid,
-					      const CamelMessageInfo *info);
+GType		camel_imap_summary_get_type	(void);
+CamelFolderSummary *
+		camel_imap_summary_new		(CamelFolder *folder,
+						 const gchar *filename);
+void		camel_imap_summary_add_offline	(CamelFolderSummary *summary,
+						 const gchar *uid,
+						 CamelMimeMessage *message,
+						 const CamelMessageInfo *info);
+void		camel_imap_summary_add_offline_uncached
+						(CamelFolderSummary *summary,
+						 const gchar *uid,
+						 const CamelMessageInfo *info);
 
 G_END_DECLS
 
diff --git a/camel/providers/imap/camel-imap-wrapper.c b/camel/providers/imap/camel-imap-wrapper.c
index d3088e9..099ac9b 100644
--- a/camel/providers/imap/camel-imap-wrapper.c
+++ b/camel/providers/imap/camel-imap-wrapper.c
@@ -92,6 +92,7 @@ imap_wrapper_finalize (GObject *object)
 static gssize
 imap_wrapper_write_to_stream (CamelDataWrapper *data_wrapper,
                               CamelStream *stream,
+                              GCancellable *cancellable,
                               GError **error)
 {
 	CamelImapWrapper *imap_wrapper = CAMEL_IMAP_WRAPPER (data_wrapper);
@@ -102,7 +103,7 @@ imap_wrapper_write_to_stream (CamelDataWrapper *data_wrapper,
 
 		datastream = camel_imap_folder_fetch_data (
 			imap_wrapper->folder, imap_wrapper->uid,
-			imap_wrapper->part_spec, FALSE, NULL);
+			imap_wrapper->part_spec, FALSE, cancellable, NULL);
 
 		if (!datastream) {
 			CAMEL_IMAP_WRAPPER_UNLOCK (imap_wrapper, lock);
@@ -125,7 +126,7 @@ imap_wrapper_write_to_stream (CamelDataWrapper *data_wrapper,
 	CAMEL_IMAP_WRAPPER_UNLOCK (imap_wrapper, lock);
 
 	return CAMEL_DATA_WRAPPER_CLASS (camel_imap_wrapper_parent_class)->
-		write_to_stream (data_wrapper, stream, error);
+		write_to_stream (data_wrapper, stream, cancellable, error);
 }
 
 static void
@@ -181,7 +182,7 @@ camel_imap_wrapper_new (CamelImapFolder *imap_folder,
 
 	/* Download the attachments if sync_offline is set, else skip them by checking only in cache */
 	stream = camel_imap_folder_fetch_data (imap_folder, uid, part_spec,
-			!sync_offline, NULL);
+			!sync_offline, NULL, NULL);
 
 	if (stream) {
 		imap_wrapper_hydrate (imap_wrapper, stream);
diff --git a/camel/providers/imapx/camel-imapx-conn-manager.c b/camel/providers/imapx/camel-imapx-conn-manager.c
index d73c77d..97517df 100644
--- a/camel/providers/imapx/camel-imapx-conn-manager.c
+++ b/camel/providers/imapx/camel-imapx-conn-manager.c
@@ -54,7 +54,7 @@ free_connection (gpointer data, gpointer user_data)
 	ConnectionInfo *cinfo = (ConnectionInfo *) data;
 	CamelIMAPXServer *conn = cinfo->conn;
 
-	camel_imapx_server_connect (conn, NULL);
+	camel_imapx_server_connect (conn, NULL, NULL);
 
 	g_object_unref (conn);
 	g_hash_table_destroy (cinfo->folders);
@@ -242,7 +242,10 @@ imapx_find_connection (CamelIMAPXConnManager *con_man, const gchar *folder_name)
 }
 
 static CamelIMAPXServer *
-imapx_create_new_connection (CamelIMAPXConnManager *con_man, const gchar *folder_name, GError **error)
+imapx_create_new_connection (CamelIMAPXConnManager *con_man,
+                             const gchar *folder_name,
+                             GCancellable *cancellable,
+                             GError **error)
 {
 	CamelIMAPXServer *conn;
 	CamelStore *store = con_man->priv->store;
@@ -253,7 +256,7 @@ imapx_create_new_connection (CamelIMAPXConnManager *con_man, const gchar *folder
 	camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
 	conn = camel_imapx_server_new (CAMEL_STORE (store), CAMEL_SERVICE (store)->url);
-	if (camel_imapx_server_connect (conn, error)) {
+	if (camel_imapx_server_connect (conn, cancellable, error)) {
 		g_object_ref (conn);
 	} else {
 		g_object_unref (conn);
@@ -307,7 +310,10 @@ camel_imapx_conn_manager_set_n_connections (CamelIMAPXConnManager *con_man, guin
 }
 
 CamelIMAPXServer *
-camel_imapx_conn_manager_get_connection (CamelIMAPXConnManager *con_man, const gchar *folder_name, GError **error)
+camel_imapx_conn_manager_get_connection (CamelIMAPXConnManager *con_man,
+                                         const gchar *folder_name,
+                                         GCancellable *cancellable,
+                                         GError **error)
 {
 	CamelIMAPXServer *conn = NULL;
 
@@ -317,7 +323,7 @@ camel_imapx_conn_manager_get_connection (CamelIMAPXConnManager *con_man, const g
 
 	conn = imapx_find_connection (con_man, folder_name);
 	if (!conn)
-		conn = imapx_create_new_connection (con_man, folder_name, error);
+		conn = imapx_create_new_connection (con_man, folder_name, cancellable, error);
 
 	CON_UNLOCK (con_man);
 
diff --git a/camel/providers/imapx/camel-imapx-conn-manager.h b/camel/providers/imapx/camel-imapx-conn-manager.h
index ed866ba..65171bd 100644
--- a/camel/providers/imapx/camel-imapx-conn-manager.h
+++ b/camel/providers/imapx/camel-imapx-conn-manager.h
@@ -61,6 +61,7 @@ void			camel_imapx_conn_manager_set_n_connections	(CamelIMAPXConnManager *con_ma
 									guint n_connections);
 CamelIMAPXServer *	camel_imapx_conn_manager_get_connection		(CamelIMAPXConnManager *con_man,
 									const gchar *folder_name,
+									GCancellable *cancellable,
 									GError **error);
 void			camel_imapx_conn_manager_close_connections	(CamelIMAPXConnManager *con_man);
 GSList *		camel_imapx_conn_manager_get_connections	(CamelIMAPXConnManager *con_man);
diff --git a/camel/providers/imapx/camel-imapx-folder.c b/camel/providers/imapx/camel-imapx-folder.c
index e3cfa03..dcefdc9 100644
--- a/camel/providers/imapx/camel-imapx-folder.c
+++ b/camel/providers/imapx/camel-imapx-folder.c
@@ -147,7 +147,9 @@ imapx_folder_finalize (GObject *object)
 }
 
 static gboolean
-imapx_refresh_info (CamelFolder *folder, GError **error)
+imapx_refresh_info (CamelFolder *folder,
+                    GCancellable *cancellable,
+                    GError **error)
 {
 	CamelStore *parent_store;
 	CamelIMAPXStore *istore;
@@ -168,9 +170,9 @@ imapx_refresh_info (CamelFolder *folder, GError **error)
 	if (!camel_service_connect ((CamelService *)istore, error))
 		return FALSE;
 
-	server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (folder), error);
+	server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (folder), cancellable, error);
 	if (server != NULL) {
-		success = camel_imapx_server_refresh_info (server, folder, error);
+		success = camel_imapx_server_refresh_info (server, folder, cancellable, error);
 		camel_imapx_store_op_done (istore, server, camel_folder_get_full_name (folder));
 		g_object_unref (server);
 	}
@@ -179,7 +181,9 @@ imapx_refresh_info (CamelFolder *folder, GError **error)
 }
 
 static gboolean
-imapx_expunge (CamelFolder *folder, GError **error)
+imapx_expunge (CamelFolder *folder,
+               GCancellable *cancellable,
+               GError **error)
 {
 	CamelStore *parent_store;
 	CamelIMAPXStore *istore;
@@ -196,9 +200,9 @@ imapx_expunge (CamelFolder *folder, GError **error)
 		return FALSE;
 	}
 
-	server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (folder), error);
+	server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (folder), cancellable, error);
 	if (server) {
-		camel_imapx_server_expunge (server, folder, error);
+		camel_imapx_server_expunge (server, folder, cancellable, error);
 		camel_imapx_store_op_done (istore, server, camel_folder_get_full_name (folder));
 		g_object_unref (server);
 		return TRUE;
@@ -208,7 +212,10 @@ imapx_expunge (CamelFolder *folder, GError **error)
 }
 
 static gboolean
-imapx_sync (CamelFolder *folder, gboolean expunge, GError **error)
+imapx_sync (CamelFolder *folder,
+            gboolean expunge,
+            GCancellable *cancellable,
+            GError **error)
 {
 	CamelStore *parent_store;
 	CamelIMAPXStore *istore;
@@ -225,17 +232,17 @@ imapx_sync (CamelFolder *folder, gboolean expunge, GError **error)
 		return FALSE;
 	}
 
-	server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (folder), error);
+	server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (folder), cancellable, error);
 	if (!server)
 		return FALSE;
 
-	camel_imapx_server_sync_changes (server, folder, NULL);
+	camel_imapx_server_sync_changes (server, folder, cancellable NULL);
 
 	/* Sync twice - make sure deleted flags are written out,
 	   then sync again incase expunge changed anything */
 
 	if (expunge)
-		camel_imapx_server_expunge (server, folder, NULL);
+		camel_imapx_server_expunge (server, folder, cancellable, NULL);
 
 	camel_imapx_store_op_done (istore, server, camel_folder_get_full_name (folder));
 	g_object_unref (server);
@@ -244,7 +251,10 @@ imapx_sync (CamelFolder *folder, gboolean expunge, GError **error)
 }
 
 static CamelMimeMessage *
-imapx_get_message (CamelFolder *folder, const gchar *uid, GError **error)
+imapx_get_message (CamelFolder *folder,
+                   const gchar *uid,
+                   GCancellable *cancellable,
+                   GError **error)
 {
 	CamelMimeMessage *msg = NULL;
 	CamelStream *stream = NULL;
@@ -283,9 +293,9 @@ imapx_get_message (CamelFolder *folder, const gchar *uid, GError **error)
 			return NULL;
 		}
 
-		server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (folder), error);
+		server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (folder), cancellable, error);
 		if (server) {
-			stream = camel_imapx_server_get_message (server, folder, uid, error);
+			stream = camel_imapx_server_get_message (server, folder, uid, cancellable, error);
 			camel_imapx_store_op_done (istore, server, camel_folder_get_full_name (folder));
 			g_object_unref (server);
 		} else
@@ -296,7 +306,7 @@ imapx_get_message (CamelFolder *folder, const gchar *uid, GError **error)
 		msg = camel_mime_message_new ();
 
 		g_mutex_lock (ifolder->stream_lock);
-		if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)msg, stream, error) == -1) {
+		if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)msg, stream, cancellable, error) == -1) {
 			g_object_unref (msg);
 			msg = NULL;
 		}
@@ -308,7 +318,10 @@ imapx_get_message (CamelFolder *folder, const gchar *uid, GError **error)
 }
 
 static gboolean
-imapx_sync_message (CamelFolder *folder, const gchar *uid, GError **error)
+imapx_sync_message (CamelFolder *folder,
+                    const gchar *uid,
+                    GCancellable *cancellable,
+                    GError **error)
 {
 	CamelStore *parent_store;
 	CamelIMAPXStore *istore;
@@ -326,11 +339,11 @@ imapx_sync_message (CamelFolder *folder, const gchar *uid, GError **error)
 		return FALSE;
 	}
 
-	server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (folder), error);
+	server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (folder), cancellable, error);
 	if (server == NULL)
 		return FALSE;
 
-	success = camel_imapx_server_sync_message (server, folder, uid, error);
+	success = camel_imapx_server_sync_message (server, folder, uid, cancellable, error);
 	camel_imapx_store_op_done (istore, server, camel_folder_get_full_name (folder));
 	g_object_unref (server);
 
@@ -338,9 +351,13 @@ imapx_sync_message (CamelFolder *folder, const gchar *uid, GError **error)
 }
 
 static gboolean
-imapx_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
-		      CamelFolder *dest, GPtrArray **transferred_uids,
-		      gboolean delete_originals, GError **error)
+imapx_transfer_messages_to (CamelFolder *source,
+                            GPtrArray *uids,
+                            CamelFolder *dest,
+                            GPtrArray **transferred_uids,
+                            gboolean delete_originals,
+                            GCancellable *cancellable,
+                            GError **error)
 {
 	CamelStore *parent_store;
 	CamelIMAPXStore *istore;
@@ -358,20 +375,25 @@ imapx_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
 		return FALSE;
 	}
 
-	server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (source), error);
+	server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (source), cancellable, error);
 	if (server) {
-		success = camel_imapx_server_copy_message (server, source, dest, uids, delete_originals, error);
+		success = camel_imapx_server_copy_message (server, source, dest, uids, delete_originals, cancellable, error);
 		camel_imapx_store_op_done (istore, server, camel_folder_get_full_name (source));
 		g_object_unref (server);
 	}
 
-	imapx_refresh_info (dest, NULL);
+	imapx_refresh_info (dest, cancellable, NULL);
 
 	return success;
 }
 
 static gboolean
-imapx_append_message (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, gchar **appended_uid, GError **error)
+imapx_append_message (CamelFolder *folder,
+                      CamelMimeMessage *message,
+                      const CamelMessageInfo *info,
+                      gchar **appended_uid,
+                      GCancellable *cancellable,
+                      GError **error)
 {
 	CamelStore *parent_store;
 	CamelIMAPXStore *istore;
@@ -392,9 +414,10 @@ imapx_append_message (CamelFolder *folder, CamelMimeMessage *message, const Came
 	if (appended_uid)
 		*appended_uid = NULL;
 
-	server = camel_imapx_store_get_server (istore, NULL, error);
+	server = camel_imapx_store_get_server (istore, NULL, cancellable, error);
 	if (server) {
-		success = camel_imapx_server_append_message (server, folder, message, info, error);
+		success = camel_imapx_server_append_message (
+			server, folder, message, info, cancellable, error);
 		g_object_unref (server);
 	}
 
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index 760d0cc..35dd739 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -96,7 +96,7 @@ void imapx_uidset_init (struct _uidset_state *ss, gint total, gint limit);
 gint imapx_uidset_done (struct _uidset_state *ss, struct _CamelIMAPXCommand *ic);
 gint imapx_uidset_add (struct _uidset_state *ss, struct _CamelIMAPXCommand *ic, const gchar *uid);
 static gboolean imapx_command_idle_stop (CamelIMAPXServer *is, GError **error);
-static gint imapx_continuation (CamelIMAPXServer *imap, gboolean litplus, GError **error);
+static gint imapx_continuation(CamelIMAPXServer *imap, gboolean litplus, GCancellable *cancellable, GError **error);
 static gboolean imapx_disconnect (CamelIMAPXServer *is);
 static gint imapx_uid_cmp (gconstpointer ap, gconstpointer bp, gpointer data);
 
@@ -146,6 +146,7 @@ struct _CamelIMAPXCommand {
 
 	/* If exception is set, it means we were not able to parse above status, it might be
 	   because user cancelled the operation or io error */
+	GCancellable *cancellable;
 	GError *error;
 
 	guint32 tag;
@@ -162,10 +163,10 @@ struct _CamelIMAPXCommand {
 	struct _CamelIMAPXJob *job;
 };
 
-CamelIMAPXCommand *camel_imapx_command_new (CamelIMAPXServer *is, const gchar *name, CamelFolder *select, const gchar *fmt, ...);
-void camel_imapx_command_add (CamelIMAPXCommand *ic, const gchar *fmt, ...);
-void camel_imapx_command_free (CamelIMAPXCommand *ic);
-void camel_imapx_command_close (CamelIMAPXCommand *ic);
+CamelIMAPXCommand *camel_imapx_command_new(CamelIMAPXServer *is, const gchar *name, CamelFolder *select, GCancellable *cancellable, const gchar *fmt, ...);
+void camel_imapx_command_add(CamelIMAPXCommand *ic, const gchar *fmt, ...);
+void camel_imapx_command_free(CamelIMAPXCommand *ic);
+void camel_imapx_command_close(CamelIMAPXCommand *ic);
 static gboolean imapx_is_command_queue_empty (CamelIMAPXServer *is);
 
 /* states for the connection? */
@@ -231,20 +232,17 @@ typedef struct _CamelIMAPXJob CamelIMAPXJob;
 struct _CamelIMAPXJob {
 	CamelMsg msg;
 
+	GCancellable *cancellable;
 	GError *error;
 
 	void (*start)(CamelIMAPXServer *is, struct _CamelIMAPXJob *job);
 
-	// ??
-	//CamelOperation *op;
-
 	gint noreply:1;		/* dont wait for reply */
 	guint32 type;		/* operation type */
 	gint pri;		/* the command priority */
 	gshort commands;		/* counts how many commands are outstanding */
 
 	CamelFolder *folder;
-	CamelOperation *op;
 
 	union {
 		struct {
@@ -318,7 +316,7 @@ static void imapx_job_fetch_new_messages_start (CamelIMAPXServer *is, CamelIMAPX
 static void imapx_command_copy_messages_step_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic);
 static gint imapx_refresh_info_uid_cmp (gconstpointer ap, gconstpointer bp);
 static gint imapx_uids_array_cmp (gconstpointer ap, gconstpointer bp);
-static gboolean imapx_server_sync_changes (CamelIMAPXServer *is, CamelFolder *folder, gint pri, GError **error);
+static gboolean imapx_server_sync_changes(CamelIMAPXServer *is, CamelFolder *folder, gint pri, GCancellable *cancellable, GError **error);
 
 enum _idle_state {
 	IMAPX_IDLE_OFF,
@@ -349,7 +347,7 @@ static void imapx_start_idle (CamelIMAPXServer *is);
 static void imapx_exit_idle (CamelIMAPXServer *is);
 static void imapx_init_idle (CamelIMAPXServer *is);
 static gboolean imapx_stop_idle (CamelIMAPXServer *is, GError **error);
-static gboolean camel_imapx_server_idle (CamelIMAPXServer *is, CamelFolder *folder, GError **error);
+static gboolean camel_imapx_server_idle (CamelIMAPXServer *is, CamelFolder *folder, GCancellable *cancellable, GError **error);
 
 enum {
 	USE_SSL_NEVER,
@@ -360,7 +358,7 @@ enum {
 #define SSL_PORT_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3)
 #define STARTTLS_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_TLS)
 
-static gboolean imapx_select (CamelIMAPXServer *is, CamelFolder *folder, gboolean force, GError **error);
+static gboolean imapx_select(CamelIMAPXServer *is, CamelFolder *folder, gboolean force, GCancellable *cancellable, GError **error);
 
 G_DEFINE_TYPE (CamelIMAPXServer, camel_imapx_server, CAMEL_TYPE_OBJECT)
 
@@ -462,10 +460,10 @@ imapx_command_add_part (CamelIMAPXCommand *ic, camel_imapx_command_part_t type,
 		/* TODO: seekable streams we could just seek to the end and back */
 		null = (CamelStreamNull *)camel_stream_null_new ();
 		if ( (type & CAMEL_IMAPX_COMMAND_MASK) == CAMEL_IMAPX_COMMAND_DATAWRAPPER) {
-			camel_data_wrapper_write_to_stream ((CamelDataWrapper *)ob, (CamelStream *)null, NULL);
+			camel_data_wrapper_write_to_stream ((CamelDataWrapper *)ob, (CamelStream *)null, NULL, NULL);
 		} else {
 			camel_stream_reset ((CamelStream *)ob, NULL);
-			camel_stream_write_to_stream ((CamelStream *)ob, (CamelStream *)null, NULL);
+			camel_stream_write_to_stream ((CamelStream *)ob, (CamelStream *)null, NULL, NULL);
 			camel_stream_reset ((CamelStream *)ob, NULL);
 		}
 		type |= CAMEL_IMAPX_COMMAND_LITERAL_PLUS;
@@ -568,11 +566,11 @@ imapx_command_addv (CamelIMAPXCommand *ic, const gchar *fmt, va_list ap)
 		switch (c) {
 		case '%':
 			if (*p == '%') {
-				camel_stream_write ((CamelStream *)ic->mem, ps, p-ps, NULL);
+				camel_stream_write ((CamelStream *)ic->mem, ps, p-ps, ic->cancellable, NULL);
 				p++;
 				ps = p;
 			} else {
-				camel_stream_write ((CamelStream *)ic->mem, ps, p-ps-1, NULL);
+				camel_stream_write ((CamelStream *)ic->mem, ps, p-ps-1, ic->cancellable, NULL);
 				start = p-1;
 				width = 0;
 				left = FALSE;
@@ -625,7 +623,7 @@ imapx_command_addv (CamelIMAPXCommand *ic, const gchar *fmt, va_list ap)
 					break;
 				case 't': /* token */
 					s = va_arg (ap, gchar *);
-					camel_stream_write ((CamelStream *)ic->mem, s, strlen (s), NULL);
+					camel_stream_write ((CamelStream *)ic->mem, s, strlen (s), ic->cancellable, NULL);
 					break;
 				case 's': /* simple string */
 					s = va_arg (ap, gchar *);
@@ -635,27 +633,27 @@ imapx_command_addv (CamelIMAPXCommand *ic, const gchar *fmt, va_list ap)
 						guchar mask = imapx_is_mask (s);
 
 						if (mask & IMAPX_TYPE_ATOM_CHAR)
-							camel_stream_write ((CamelStream *)ic->mem, s, strlen (s), NULL);
+							camel_stream_write ((CamelStream *)ic->mem, s, strlen (s), ic->cancellable, NULL);
 						else if (mask & IMAPX_TYPE_TEXT_CHAR) {
-							camel_stream_write((CamelStream *)ic->mem, "\"", 1, NULL);
+							camel_stream_write((CamelStream *)ic->mem, "\"", 1, ic->cancellable, NULL);
 							while (*s) {
 								gchar *start = s;
 
 								while (*s && imapx_is_quoted_char (*s))
 									s++;
-								camel_stream_write ((CamelStream *)ic->mem, start, s-start, NULL);
+								camel_stream_write ((CamelStream *)ic->mem, start, s-start, ic->cancellable, NULL);
 								if (*s) {
-									camel_stream_write((CamelStream *)ic->mem, "\\", 1, NULL);
-									camel_stream_write ((CamelStream *)ic->mem, s, 1, NULL);
+									camel_stream_write((CamelStream *)ic->mem, "\\", 1, ic->cancellable, NULL);
+									camel_stream_write ((CamelStream *)ic->mem, s, 1, ic->cancellable, NULL);
 									s++;
 								}
 							}
-							camel_stream_write((CamelStream *)ic->mem, "\"", 1, NULL);
+							camel_stream_write((CamelStream *)ic->mem, "\"", 1, ic->cancellable, NULL);
 						} else {
 							imapx_command_add_part (ic, CAMEL_IMAPX_COMMAND_STRING, s);
 						}
 					} else {
-						camel_stream_write((CamelStream *)ic->mem, "\"\"", 2, NULL);
+						camel_stream_write((CamelStream *)ic->mem, "\"\"", 2, ic->cancellable, NULL);
 					}
 					if (encoded) {
 						g_free (encoded);
@@ -678,18 +676,18 @@ imapx_command_addv (CamelIMAPXCommand *ic, const gchar *fmt, va_list ap)
 						s = encoded;
 						goto output_string;
 					} else
-						camel_stream_write((CamelStream *)ic->mem, "\"\"", 2, NULL);
+						camel_stream_write((CamelStream *)ic->mem, "\"\"", 2, ic->cancellable, NULL);
 
 					break;
 				case 'F': /* IMAP flags set */
 					f = va_arg (ap, guint32);
 					F = va_arg (ap, CamelFlag *);
-					imapx_write_flags ((CamelStream *)ic->mem, f, F, NULL);
+					imapx_write_flags ((CamelStream *)ic->mem, f, F, ic->cancellable, NULL);
 					break;
 				case 'c':
 					d = va_arg (ap, gint);
 					ch = d;
-					camel_stream_write ((CamelStream *)ic->mem, &ch, 1, NULL);
+					camel_stream_write ((CamelStream *)ic->mem, &ch, 1, ic->cancellable, NULL);
 					break;
 				case 'd': /* int/unsigned */
 				case 'u':
@@ -716,28 +714,36 @@ imapx_command_addv (CamelIMAPXCommand *ic, const gchar *fmt, va_list ap)
 			c = *p;
 			if (c) {
 				g_assert (c == '\\');
-				camel_stream_write ((CamelStream *)ic->mem, ps, p-ps, NULL);
+				camel_stream_write ((CamelStream *)ic->mem, ps, p-ps, ic->cancellable, NULL);
 				p++;
 				ps = p;
 			}
 		}
 	}
 
-	camel_stream_write ((CamelStream *)ic->mem, ps, p-ps-1, NULL);
+	camel_stream_write ((CamelStream *)ic->mem, ps, p-ps-1, ic->cancellable, NULL);
 }
 
 CamelIMAPXCommand *
-camel_imapx_command_new (CamelIMAPXServer *is, const gchar *name, CamelFolder *select, const gchar *fmt, ...)
+camel_imapx_command_new (CamelIMAPXServer *is,
+                         const gchar *name,
+                         CamelFolder *select,
+                         GCancellable *cancellable,
+                         const gchar *fmt, ...)
 {
 	CamelIMAPXCommand *ic;
 	static gint tag = 0;
 	va_list ap;
 
-	ic = g_malloc0 (sizeof (*ic));
+	if (cancellable != NULL)
+		g_object_ref (cancellable);
+
+	ic = g_malloc0(sizeof(*ic));
 	ic->tag = tag++;
 	ic->name = name;
 	ic->mem = (CamelStreamMem *)camel_stream_mem_new ();
 	ic->select = select;
+	ic->cancellable = cancellable;
 	ic->is = is;
 	camel_dlist_init (&ic->parts);
 
@@ -791,6 +797,9 @@ camel_imapx_command_free (CamelIMAPXCommand *ic)
 		g_free (cp);
 	}
 
+	if (ic->cancellable != NULL)
+		g_object_unref (ic->cancellable);
+
 	/* Do NOT try to free the GError.  If set it should have been
 	 * propagated to the CamelIMAPXJob, so it's either NULL or the
 	 * CamelIMAPXJob owns it now. */
@@ -852,7 +861,7 @@ imapx_command_start (CamelIMAPXServer *imap, CamelIMAPXCommand *ic)
 	while (imap->literal == ic &&
 	       ic->current->type & CAMEL_IMAPX_COMMAND_LITERAL_PLUS) {
 		/* Sent LITERAL+ continuation immediately */
-		if (!imapx_continuation (imap, TRUE, &ic->error))
+		if (!imapx_continuation(imap, TRUE, ic->cancellable, &ic->error))
 			goto err;
 	}
 
@@ -895,7 +904,9 @@ static gboolean duplicate_fetch_or_refresh (CamelIMAPXServer *is, CamelIMAPXComm
 	must have QUEUE lock */
 
 static void
-imapx_command_start_next (CamelIMAPXServer *is, GError **error)
+imapx_command_start_next (CamelIMAPXServer *is,
+                          GCancellable *cancellable,
+                          GError **error)
 {
 	CamelIMAPXCommand *ic, *nc;
 	gint count = 0;
@@ -1007,7 +1018,7 @@ imapx_command_start_next (CamelIMAPXServer *is, GError **error)
 	if (ic->select) {
 		c(is->tagprefix, "Selecting folder '%s' for command '%s'(%p)\n",
 		  camel_folder_get_full_name (ic->select), ic->name, ic);
-		imapx_select (is, ic->select, FALSE, error);
+		imapx_select (is, ic->select, FALSE, cancellable, error);
 	} else {
 		pri = ic->pri;
 		nc = ic->next;
@@ -1039,7 +1050,8 @@ imapx_is_command_queue_empty (CamelIMAPXServer *is)
 }
 
 static void
-imapx_command_queue (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
+imapx_command_queue (CamelIMAPXServer *is,
+                     CamelIMAPXCommand *ic)
 {
 	CamelIMAPXCommand *scan;
 
@@ -1079,7 +1091,7 @@ imapx_command_queue (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 		scan->prev = ic;
 	}
 
-	imapx_command_start_next (is, NULL);
+	imapx_command_start_next (is, ic->cancellable, NULL);
 
 	QUEUE_UNLOCK (is);
 
@@ -1222,7 +1234,9 @@ imapx_expunge_uid_from_summary (CamelIMAPXServer *imap, gchar *uid, gboolean uns
 
 /* handle any untagged responses */
 static gint
-imapx_untagged (CamelIMAPXServer *imap, GError **error)
+imapx_untagged (CamelIMAPXServer *imap,
+                GCancellable *cancellable,
+                GError **error)
 {
 	guint id, len;
 	guchar *token, *p, c;
@@ -1232,13 +1246,13 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error)
 
 	e(imap->tagprefix, "got untagged response\n");
 	id = 0;
-	tok = camel_imapx_stream_token (imap->stream, &token, &len, error);
+	tok = camel_imapx_stream_token (imap->stream, &token, &len, cancellable, error);
 	if (tok < 0)
 		return -1;
 
 	if (tok == IMAPX_TOK_INT) {
 		id = strtoul ((gchar *) token, NULL, 10);
-		tok = camel_imapx_stream_token (imap->stream, &token, &len, error);
+		tok = camel_imapx_stream_token (imap->stream, &token, &len, cancellable, error);
 		if (tok < 0)
 			return -1;
 	}
@@ -1259,7 +1273,7 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error)
 	case IMAPX_CAPABILITY:
 		if (imap->cinfo)
 			imapx_free_capability (imap->cinfo);
-		imap->cinfo = imapx_parse_capability (imap->stream, error);
+		imap->cinfo = imapx_parse_capability (imap->stream, cancellable, error);
 		if (imap->cinfo == NULL)
 			return -1;
 		c(imap->tagprefix, "got capability flags %08x\n", imap->cinfo->capa);
@@ -1293,21 +1307,21 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error)
 		guchar *token;
 		gint tok;
 
-		tok = camel_imapx_stream_token (imap->stream, &token, &len, error);
+		tok = camel_imapx_stream_token (imap->stream, &token, &len, cancellable, error);
 		if (tok < 0)
 			return -1;
 		if (tok == '(') {
 			unsolicited = FALSE;
 			while (tok != ')') {
 				/* We expect this to be 'EARLIER' */
-				tok = camel_imapx_stream_token (imap->stream, &token, &len, error);
+				tok = camel_imapx_stream_token (imap->stream, &token, &len, cancellable, error);
 				if (tok < 0)
 					return -1;
 			}
 		} else
 			camel_imapx_stream_ungettoken (imap->stream, tok, token, len);
 
-		uids = imapx_parse_uids (imap->stream, error);
+		uids = imapx_parse_uids (imap->stream, cancellable, error);
 		if (uids == NULL)
 			return -1;
 		for (i = 0; i < uids->len; i++) {
@@ -1321,7 +1335,7 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error)
 	case IMAPX_NAMESPACE: {
 		CamelIMAPXNamespaceList *nsl = NULL;
 
-		nsl = imapx_parse_namespace_list (imap->stream, error);
+		nsl = imapx_parse_namespace_list (imap->stream, cancellable, error);
 		if (nsl != NULL) {
 			CamelIMAPXStore *imapx_store = (CamelIMAPXStore *) imap->store;
 			CamelIMAPXStoreNamespace *ns;
@@ -1353,7 +1367,7 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error)
 	case IMAPX_FLAGS: {
 		guint32 flags;
 
-		imapx_parse_flags (imap->stream, &flags, NULL, error);
+		imapx_parse_flags (imap->stream, &flags, NULL, cancellable, error);
 
 		c(imap->tagprefix, "flags: %08x\n", flags);
 		break;
@@ -1361,7 +1375,7 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error)
 	case IMAPX_FETCH: {
 		struct _fetch_info *finfo;
 
-		finfo = imapx_parse_fetch (imap->stream, error);
+		finfo = imapx_parse_fetch (imap->stream, cancellable, error);
 		if (finfo == NULL) {
 			imapx_free_fetch (finfo);
 			return -1;
@@ -1379,7 +1393,7 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error)
 					camel_seekable_stream_seek ((CamelSeekableStream *)job->u.get_message.stream, finfo->offset, CAMEL_STREAM_SET, NULL);
 				}
 
-				job->u.get_message.body_len = camel_stream_write_to_stream (finfo->body, job->u.get_message.stream, &job->error);
+				job->u.get_message.body_len = camel_stream_write_to_stream (finfo->body, job->u.get_message.stream, job->cancellable, &job->error);
 				if (job->u.get_message.body_len == -1)
 					g_prefix_error (
 						&job->error,
@@ -1541,6 +1555,7 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error)
 
 					if (!camel_folder_summary_check_uid (job->folder->summary, mi->uid)) {
 						CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *)job->folder;
+						gint cnt;
 
 						camel_folder_summary_add (job->folder->summary, mi);
 						imapx_set_message_info_flags_for_new_message (mi, server_flags, server_user_flags, job->folder);
@@ -1551,10 +1566,8 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error)
 							g_hash_table_remove (ifolder->ignore_recent, mi->uid);
 						}
 
-						if (job->op) {
-							gint cnt = (camel_folder_summary_count (job->folder->summary) * 100 )/ifolder->exists_on_server;
-							camel_operation_progress (job->op, cnt?cnt:1);
-						}
+						cnt = (camel_folder_summary_count (job->folder->summary) * 100 )/ifolder->exists_on_server;
+						camel_operation_progress (job->cancellable, cnt?cnt:1);
 					}
 
 					if (free_user_flags && server_user_flags)
@@ -1570,7 +1583,7 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error)
 	case IMAPX_LSUB:
 		lsub = TRUE;
 	case IMAPX_LIST: {
-		struct _list_info *linfo = imapx_parse_list (imap->stream, error);
+		struct _list_info *linfo = imapx_parse_list (imap->stream, cancellable, error);
 		CamelIMAPXJob *job;
 
 		if (!linfo)
@@ -1602,7 +1615,7 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error)
 		imap->recent = id;
 		break;
 	case IMAPX_STATUS: {
-		struct _state_info *sinfo = imapx_parse_status_info (imap->stream, error);
+		struct _state_info *sinfo = imapx_parse_status_info (imap->stream, cancellable, error);
 		if (sinfo) {
 			CamelIMAPXStoreSummary *s = ((CamelIMAPXStore *)imap->store)->summary;
 			CamelIMAPXStoreNamespace *ns;
@@ -1615,7 +1628,7 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error)
 				path_name = camel_imapx_store_summary_full_to_path (s, sinfo->name, ns->sep);
 				c(imap->tagprefix, "Got folder path '%s' for full '%s'\n", path_name, sinfo->name);
 				if (path_name) {
-					ifolder = (gpointer)camel_store_get_folder (imap->store, path_name, 0, error);
+					ifolder = (gpointer)camel_store_get_folder (imap->store, path_name, 0, cancellable, error);
 					g_free (path_name);
 				}
 			}
@@ -1637,7 +1650,7 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error)
 	case IMAPX_BYE: {
 		guchar *token;
 
-		if (camel_imapx_stream_text (imap->stream, &token, NULL)) {
+		if (camel_imapx_stream_text (imap->stream, &token, cancellable, NULL)) {
 			c(imap->tagprefix, "BYE: %s\n", token);
 			g_set_error (
 				error, CAMEL_IMAPX_ERROR, 1,
@@ -1655,7 +1668,7 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error)
 		/* TODO: validate which ones of these can happen as unsolicited responses */
 		/* TODO: handle bye/preauth differently */
 		camel_imapx_stream_ungettoken (imap->stream, tok, token, len);
-		sinfo = imapx_parse_status (imap->stream, error);
+		sinfo = imapx_parse_status (imap->stream, cancellable, error);
 		if (sinfo == NULL)
 			return -1;
 		switch (sinfo->condition) {
@@ -1714,13 +1727,16 @@ imapx_untagged (CamelIMAPXServer *imap, GError **error)
 		c(imap->tagprefix, "unknown token: %s\n", token);
 	}
 
-	return camel_imapx_stream_skip (imap->stream, error);
+	return camel_imapx_stream_skip (imap->stream, cancellable, error);
 }
 
 /* handle any continuation requests
    either data continuations, or auth continuation */
 static gint
-imapx_continuation (CamelIMAPXServer *imap, gboolean litplus, GError **error)
+imapx_continuation (CamelIMAPXServer *imap,
+                    gboolean litplus,
+                    GCancellable *cancellable,
+                    GError **error)
 {
 	CamelIMAPXCommand *ic, *newliteral = NULL;
 	CamelIMAPXCommandPart *cp;
@@ -1730,7 +1746,7 @@ imapx_continuation (CamelIMAPXServer *imap, gboolean litplus, GError **error)
 	   ohter lock here.  All other writes go through
 	   queue-lock */
 	if (imapx_idle_supported (imap) && imapx_in_idle (imap)) {
-		camel_imapx_stream_skip (imap->stream, error);
+		camel_imapx_stream_skip (imap->stream, cancellable, error);
 
 		c(imap->tagprefix, "Got continuation response for IDLE \n");
 		IDLE_LOCK (imap->idle);
@@ -1754,8 +1770,8 @@ imapx_continuation (CamelIMAPXServer *imap, gboolean litplus, GError **error)
 
 		QUEUE_LOCK (imap);
 		imap->literal = NULL;
-		imapx_command_start_next (imap, error);
-		QUEUE_UNLOCK (imap);
+		imapx_command_start_next (imap, cancellable, error);
+		QUEUE_UNLOCK(imap);
 
 		return 1;
 	}
@@ -1763,7 +1779,7 @@ imapx_continuation (CamelIMAPXServer *imap, gboolean litplus, GError **error)
 	ic = imap->literal;
 	if (!litplus) {
 		if (ic == NULL) {
-			camel_imapx_stream_skip (imap->stream, error);
+			camel_imapx_stream_skip (imap->stream, cancellable, error);
 			c(imap->tagprefix, "got continuation response with no outstanding continuation requests?\n");
 			return 1;
 		}
@@ -1776,26 +1792,28 @@ imapx_continuation (CamelIMAPXServer *imap, gboolean litplus, GError **error)
 	switch (cp->type & CAMEL_IMAPX_COMMAND_MASK) {
 	case CAMEL_IMAPX_COMMAND_DATAWRAPPER:
 		c(imap->tagprefix, "writing data wrapper to literal\n");
-		camel_data_wrapper_write_to_stream ((CamelDataWrapper *)cp->ob, (CamelStream *)imap->stream, NULL);
+		camel_data_wrapper_write_to_stream ((CamelDataWrapper *)cp->ob, (CamelStream *)imap->stream, cancellable, NULL);
 		break;
 	case CAMEL_IMAPX_COMMAND_STREAM:
 		c(imap->tagprefix, "writing stream to literal\n");
-		camel_stream_write_to_stream ((CamelStream *)cp->ob, (CamelStream *)imap->stream, NULL);
+		camel_stream_write_to_stream ((CamelStream *)cp->ob, (CamelStream *)imap->stream, cancellable, NULL);
 		break;
 	case CAMEL_IMAPX_COMMAND_AUTH: {
 		gchar *resp;
 		guchar *token;
 
-		if (camel_imapx_stream_text (imap->stream, &token, error))
+		if (camel_imapx_stream_text (imap->stream, &token, cancellable, error))
 			return -1;
-
-		resp = camel_sasl_challenge_base64 ((CamelSasl *)cp->ob, (const gchar *) token, error);
-		g_free (token);
+		    
+		resp = camel_sasl_challenge_base64 (
+			(CamelSasl *) cp->ob, (const gchar *) token,
+			cancellable, error);
+		g_free(token);
 		if (resp == NULL)
 			return -1;
 		c(imap->tagprefix, "got auth continuation, feeding token '%s' back to auth mech\n", resp);
 
-		camel_stream_write ((CamelStream *)imap->stream, resp, strlen (resp), NULL);
+		camel_stream_write ((CamelStream *)imap->stream, resp, strlen (resp), cancellable, NULL);
 		g_free (resp);
 		/* we want to keep getting called until we get a status reponse from the server
 		   ignore what sasl tells us */
@@ -1810,14 +1828,14 @@ imapx_continuation (CamelIMAPXServer *imap, gboolean litplus, GError **error)
 
 		// FIXME: errors
 		if (cp->ob && (file = camel_stream_fs_new_with_name (cp->ob, O_RDONLY, 0, NULL))) {
-			camel_stream_write_to_stream (file, (CamelStream *)imap->stream, NULL);
+			camel_stream_write_to_stream (file, (CamelStream *)imap->stream, cancellable, NULL);
 			g_object_unref (file);
 		} else if (cp->ob_size > 0) {
 			// Server is expecting data ... ummm, send it zeros?  abort?
 		}
 		break; }
 	case CAMEL_IMAPX_COMMAND_STRING:
-		camel_stream_write ((CamelStream *)imap->stream, cp->ob, cp->ob_size, NULL);
+		camel_stream_write ((CamelStream *)imap->stream, cp->ob, cp->ob_size, cancellable, NULL);
 		break;
 	default:
 		/* should we just ignore? */
@@ -1829,7 +1847,7 @@ imapx_continuation (CamelIMAPXServer *imap, gboolean litplus, GError **error)
 	}
 
 	if (!litplus)
-		camel_imapx_stream_skip (imap->stream, error);
+		camel_imapx_stream_skip (imap->stream, cancellable, error);
  noskip:
 	cp = cp->next;
 	if (cp->next) {
@@ -1850,15 +1868,19 @@ imapx_continuation (CamelIMAPXServer *imap, gboolean litplus, GError **error)
 	imap->literal = newliteral;
 
 	if (!litplus)
-		imapx_command_start_next (imap, error);
-	QUEUE_UNLOCK (imap);
+		imapx_command_start_next(imap, cancellable, error);
+	QUEUE_UNLOCK(imap);
 
 	return 1;
 }
 
 /* handle a completion line */
 static gint
-imapx_completion (CamelIMAPXServer *imap, guchar *token, gint len, GError **error)
+imapx_completion (CamelIMAPXServer *imap,
+                  guchar *token,
+                  gint len,
+                  GCancellable *cancellable,
+                  GError **error)
 {
 	CamelIMAPXCommand *ic;
 	guint tag;
@@ -1923,36 +1945,38 @@ imapx_completion (CamelIMAPXServer *imap, guchar *token, gint len, GError **erro
 	camel_dlist_remove ((CamelDListNode *) ic);
 	QUEUE_UNLOCK (imap);
 
-	ic->status = imapx_parse_status (imap->stream, error);
+	ic->status = imapx_parse_status (imap->stream, cancellable, error);
 
 	if (ic->complete)
 		ic->complete (imap, ic);
 
-	QUEUE_LOCK (imap);
-	imapx_command_start_next (imap, error);
-	QUEUE_UNLOCK (imap);
+	QUEUE_LOCK(imap);
+	imapx_command_start_next(imap, cancellable, error);
+	QUEUE_UNLOCK(imap);
 
 	return 1;
 }
 
 static void
-imapx_step (CamelIMAPXServer *is, GError **error)
+imapx_step (CamelIMAPXServer *is,
+            GCancellable *cancellable,
+            GError **error)
 {
 	guint len;
 	guchar *token;
 	gint tok;
 
 	// poll ?  wait for other stuff? loop?
-	tok = camel_imapx_stream_token (is->stream, &token, &len, error);
+	tok = camel_imapx_stream_token (is->stream, &token, &len, cancellable, error);
 	if (tok < 0)
 		return;
 
 	if (tok == '*')
-		imapx_untagged (is, error);
+		imapx_untagged (is, cancellable, error);
 	else if (tok == IMAPX_TOK_TOKEN)
-		imapx_completion (is, token, len, error);
+		imapx_completion (is, token, len, cancellable, error);
 	else if (tok == '+')
-		imapx_continuation (is, FALSE, error);
+		imapx_continuation (is, FALSE, cancellable, error);
 	else
 		g_set_error (
 			error, CAMEL_IMAPX_ERROR, 1,
@@ -1972,7 +1996,7 @@ imapx_command_run (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 	QUEUE_UNLOCK (is);
 
 	while (ic->status == NULL && ic->error == NULL)
-		imapx_step (is, &ic->error);
+		imapx_step (is, ic->cancellable, &ic->error);
 
 	if (is->literal == ic)
 		is->literal = NULL;
@@ -2012,6 +2036,20 @@ imapx_command_run_sync (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 /* ********************************************************************** */
 /* Should be called when there are no more commands needed to complete the job */
 
+static CamelIMAPXJob *
+imapx_job_new (GCancellable *cancellable)
+{
+	CamelIMAPXJob *job;
+
+	if (cancellable != NULL)
+		g_object_ref (cancellable);
+
+	job = g_malloc0 (sizeof (CamelIMAPXJob));
+	job->cancellable = cancellable;
+
+	return job;
+}
+
 static void
 imapx_job_done (CamelIMAPXServer *is, CamelIMAPXJob *job)
 {
@@ -2115,7 +2153,8 @@ imapx_command_idle_stop (CamelIMAPXServer *is, GError **error)
 }
 
 static void
-imapx_command_idle_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
+imapx_command_idle_done (CamelIMAPXServer *is,
+                         CamelIMAPXCommand *ic)
 {
 	CamelIMAPXIdle *idle = is->idle;
 
@@ -2137,7 +2176,8 @@ imapx_command_idle_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 }
 
 static void
-imapx_job_idle_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
+imapx_job_idle_start (CamelIMAPXServer *is,
+                      CamelIMAPXJob *job)
 {
 	CamelIMAPXCommand *ic;
 	CamelIMAPXCommandPart *cp;
@@ -2145,7 +2185,9 @@ imapx_job_idle_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 
 	full_name = camel_folder_get_full_name (job->folder);
 
-	ic = camel_imapx_command_new (is, "IDLE", job->folder, "IDLE");
+	ic = camel_imapx_command_new (
+		is, "IDLE", job->folder,
+		job->cancellable, "IDLE");
 	ic->job = job;
 	ic->pri = job->pri;
 	ic->complete = imapx_command_idle_done;
@@ -2169,12 +2211,15 @@ imapx_job_idle_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 }
 
 static gboolean
-camel_imapx_server_idle (CamelIMAPXServer *is, CamelFolder *folder, GError **error)
+camel_imapx_server_idle (CamelIMAPXServer *is,
+                         CamelFolder *folder,
+                         GCancellable *cancellable,
+                         GError **error)
 {
 	CamelIMAPXJob *job;
 	gboolean success;
 
-	job = g_malloc0 (sizeof (*job));
+	job = imapx_job_new (cancellable);
 	job->type = IMAPX_JOB_IDLE;
 	job->start = imapx_job_idle_start;
 	job->folder = folder;
@@ -2191,19 +2236,19 @@ imapx_server_fetch_new_messages (CamelIMAPXServer *is,
                                  CamelFolder *folder,
                                  gboolean async,
                                  gboolean update_unseen,
+                                 GCancellable *cancellable,
                                  GError **error)
 {
 	CamelIMAPXJob *job;
 	gboolean success;
 
-	job = g_malloc0 (sizeof (*job));
+	job = imapx_job_new (cancellable);
 	job->type = IMAPX_JOB_FETCH_NEW_MESSAGES;
 	job->start = imapx_job_fetch_new_messages_start;
 	job->folder = folder;
 	job->noreply = async;
 	job->u.refresh_info.changes = camel_folder_change_info_new ();
 	job->u.refresh_info.update_unseen = update_unseen;
-	job->op = camel_operation_registered ();
 
 	success = imapx_submit_job (is, job, error);
 
@@ -2217,8 +2262,11 @@ static gpointer
 imapx_idle_thread (gpointer data)
 {
 	CamelIMAPXServer *is = (CamelIMAPXServer *) data;
+	GCancellable *cancellable;
 	GError *local_error = NULL;
 
+	cancellable = g_object_ref (is->cancellable);
+
 	while (TRUE) {
 		CamelIMAPXFolder *ifolder;
 
@@ -2237,11 +2285,12 @@ imapx_idle_thread (gpointer data)
 				continue;
 			}
 			IDLE_UNLOCK (is->idle);
-			camel_imapx_server_idle (is, (gpointer)ifolder, &local_error);
+
+			camel_imapx_server_idle (is, (gpointer)ifolder, cancellable, &local_error);
 
 			if (local_error == NULL && ifolder->exists_on_server >
 			    camel_folder_summary_count (((CamelFolder *) ifolder)->summary) && imapx_is_command_queue_empty (is))
-				imapx_server_fetch_new_messages (is, is->select_folder, TRUE, TRUE, &local_error);
+				imapx_server_fetch_new_messages (is, is->select_folder, TRUE, TRUE, cancellable, &local_error);
 
 			if (local_error != NULL) {
 				e (is->tagprefix, "Caught exception in idle thread:  %s \n", local_error->message);
@@ -2258,6 +2307,8 @@ imapx_idle_thread (gpointer data)
 			break;
 	}
 
+	g_object_unref (cancellable);
+
 	g_clear_error (&local_error);
 	is->idle->idle_thread = NULL;
 	return NULL;
@@ -2454,7 +2505,7 @@ imapx_command_select_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 		ifolder->exists_on_server = is->exists;
 		ifolder->modseq_on_server = is->highestmodseq;
 		if (ifolder->uidnext_on_server < is->uidnext) {
-			imapx_server_fetch_new_messages (is, is->select_pending, TRUE, TRUE, NULL);
+			imapx_server_fetch_new_messages (is, is->select_pending, TRUE, TRUE, NULL, NULL);
 			/* We don't do this right now because we want the new messages to
 			   update the unseen count. */
 			//ifolder->uidnext_on_server = is->uidnext;
@@ -2482,7 +2533,11 @@ imapx_command_select_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 
 /* Should have a queue lock. TODO Change the way select is written */
 static gboolean
-imapx_select (CamelIMAPXServer *is, CamelFolder *folder, gboolean forced, GError **error)
+imapx_select (CamelIMAPXServer *is,
+              CamelFolder *folder,
+              gboolean forced,
+              GCancellable *cancellable,
+              GError **error)
 {
 	CamelIMAPXCommand *ic;
 	const gchar *full_name;
@@ -2533,7 +2588,7 @@ imapx_select (CamelIMAPXServer *is, CamelFolder *folder, gboolean forced, GError
 	/* Hrm, what about reconnecting? */
 	is->state = IMAPX_INITIALISED;
 
-	ic = camel_imapx_command_new(is, "SELECT", NULL, "SELECT %f", folder);
+	ic = camel_imapx_command_new(is, "SELECT", NULL, cancellable, "SELECT %f", folder);
 
 	if (is->use_qresync) {
 		CamelIMAPXSummary *isum = (CamelIMAPXSummary *)folder->summary;
@@ -2716,7 +2771,9 @@ connect_to_server_process (CamelIMAPXServer *is, const gchar *cmd, GError **erro
 #endif /* G_OS_WIN32 */
 
 gboolean
-imapx_connect_to_server (CamelIMAPXServer *is, GError **error)
+imapx_connect_to_server (CamelIMAPXServer *is,
+                         GCancellable *cancellable,
+                         GError **error)
 {
 	CamelStream * tcp_stream = NULL;
 	gchar *socks_host;
@@ -2781,7 +2838,9 @@ imapx_connect_to_server (CamelIMAPXServer *is, GError **error)
 		g_free (socks_host);
 	}
 
-	ret = camel_tcp_stream_connect (CAMEL_TCP_STREAM (tcp_stream), is->url->host, serv, fallback_port, error);
+	ret = camel_tcp_stream_connect (
+		CAMEL_TCP_STREAM (tcp_stream), is->url->host, serv,
+		fallback_port, cancellable, error);
 	if (ret == -1) {
 		g_prefix_error (
 			error, _("Could not connect to %s (port %s): "),
@@ -2815,24 +2874,26 @@ imapx_connect_to_server (CamelIMAPXServer *is, GError **error)
 			return FALSE;
 		}
 
-		tok = camel_imapx_stream_token (is->stream, &token, &len, error);
+		tok = camel_imapx_stream_token (is->stream, &token, &len, cancellable, error);
 		if (tok < 0)
 			return FALSE;
 
 		if (tok == '*') {
-			imapx_untagged (is, error);
+			imapx_untagged (is, cancellable, error);
 			break;
 		}
 		camel_imapx_stream_ungettoken (is->stream, tok, token, len);
-		if (camel_imapx_stream_text (is->stream, &token, error))
+		if (camel_imapx_stream_text (is->stream, &token, cancellable, error))
 			return FALSE;
 		e(is->tagprefix, "Got unexpected line before greeting:  '%s'\n", token);
 		g_free (token);
 	}
 
 	if (!is->cinfo) {
-		ic = camel_imapx_command_new(is, "CAPABILITY", NULL, "CAPABILITY");
-		imapx_command_run (is, ic);
+		ic = camel_imapx_command_new (
+			is, "CAPABILITY", NULL,
+			cancellable, "CAPABILITY");
+		imapx_command_run(is, ic);
 
 		if (ic->error != NULL || ic->status->result != IMAPX_OK) {
 			if (ic->error == NULL)
@@ -2862,7 +2923,9 @@ imapx_connect_to_server (CamelIMAPXServer *is, GError **error)
 			goto exit;
 		}
 
-		ic = camel_imapx_command_new (is, "STARTTLS", NULL, "STARTTLS");
+		ic = camel_imapx_command_new (
+			is, "STARTTLS", NULL,
+			cancellable, "STARTTLS");
 		imapx_command_run (is, ic);
 
 		if (ic->error != NULL || ic->status->result != IMAPX_OK) {
@@ -2899,7 +2962,9 @@ imapx_connect_to_server (CamelIMAPXServer *is, GError **error)
 		}
 		/* Get new capabilities if they weren't already given */
 		if (!is->cinfo) {
-			ic = camel_imapx_command_new(is, "CAPABILITY", NULL, "CAPABILITY");
+			ic = camel_imapx_command_new (
+				is, "CAPABILITY", NULL,
+				cancellable, "CAPABILITY");
 			if (!imapx_command_run (is, ic)) {
 				g_propagate_error (&local_error, ic->error);
 				camel_imapx_command_free (ic);
@@ -2931,7 +2996,9 @@ exit:
 }
 
 static gboolean
-imapx_reconnect (CamelIMAPXServer *is, GError **error)
+imapx_reconnect (CamelIMAPXServer *is,
+                 GCancellable *cancellable,
+                 GError **error)
 {
 	CamelSasl *sasl;
 	CamelIMAPXCommand *ic;
@@ -2950,7 +3017,7 @@ imapx_reconnect (CamelIMAPXServer *is, GError **error)
 			service->url->passwd = NULL;
 		}
 
-		if (!imapx_connect_to_server (is, error))
+		if (!imapx_connect_to_server (is, cancellable, error))
 			goto exception;
 
 		if (is->state == IMAPX_AUTHENTICATED)
@@ -3010,10 +3077,15 @@ imapx_reconnect (CamelIMAPXServer *is, GError **error)
 			}
 		}
 		if (authtype && (sasl = camel_sasl_new ("imap", authtype->authproto, service))) {
-			ic = camel_imapx_command_new (is, "AUTHENTICATE", NULL, "AUTHENTICATE %A", sasl);
+			ic = camel_imapx_command_new (
+				is, "AUTHENTICATE", NULL, cancellable,
+				"AUTHENTICATE %A", sasl);
 			g_object_unref (sasl);
 		} else {
-			ic = camel_imapx_command_new(is, "LOGIN", NULL, "LOGIN %s %s", service->url->user, service->url->passwd);
+			ic = camel_imapx_command_new (
+				is, "LOGIN", NULL, cancellable,
+				"LOGIN %s %s", service->url->user,
+				service->url->passwd);
 		}
 
 		imapx_command_run (is, ic);
@@ -3052,7 +3124,9 @@ imapx_reconnect (CamelIMAPXServer *is, GError **error)
 
 	/* After login we re-capa unless the server already told us */
 	if (!is->cinfo) {
-		ic = camel_imapx_command_new(is, "CAPABILITY", NULL, "CAPABILITY");
+		ic = camel_imapx_command_new (
+			is, "CAPABILITY", NULL,
+			cancellable, "CAPABILITY");
 		if (!imapx_command_run (is, ic)) {
 			g_propagate_error (error, ic->error);
 			camel_imapx_command_free (ic);
@@ -3075,7 +3149,9 @@ imapx_reconnect (CamelIMAPXServer *is, GError **error)
 
 	/* Fetch namespaces */
 	if (is->cinfo->capa & IMAPX_CAPABILITY_NAMESPACE) {
-		ic = camel_imapx_command_new (is, "NAMESPACE", NULL, "NAMESPACE");
+		ic = camel_imapx_command_new (
+			is, "NAMESPACE", NULL,
+			cancellable, "NAMESPACE");
 		if (!imapx_command_run (is, ic)) {
 			g_propagate_error (error, ic->error);
 			camel_imapx_command_free (ic);
@@ -3087,7 +3163,9 @@ imapx_reconnect (CamelIMAPXServer *is, GError **error)
 
 	if (((CamelIMAPXStore *)is->store)->rec_options & IMAPX_USE_QRESYNC &&
 	    is->cinfo->capa & IMAPX_CAPABILITY_QRESYNC) {
-		ic = camel_imapx_command_new (is, "ENABLE", NULL, "ENABLE CONDSTORE QRESYNC");
+		ic = camel_imapx_command_new (
+			is, "ENABLE", NULL, cancellable,
+			"ENABLE CONDSTORE QRESYNC");
 		if (!imapx_command_run (is, ic)) {
 			g_propagate_error (error, ic->error);
 			camel_imapx_command_free (ic);
@@ -3162,11 +3240,13 @@ imapx_command_fetch_message_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 		if (job->u.get_message.fetch_offset < job->u.get_message.size ||
 		    job->u.get_message.fetch_offset == really_fetched) {
 			camel_imapx_command_free (ic);
-			if (job->op)
-				camel_operation_progress (job->op, (job->u.get_message.fetch_offset *100)/job->u.get_message.size);
+			camel_operation_progress (
+				job->cancellable,
+				(job->u.get_message.fetch_offset *100)/job->u.get_message.size);
 
-			ic = camel_imapx_command_new(is, "FETCH", job->folder,
-					"UID FETCH %t (BODY.PEEK[]", job->u.get_message.uid);
+			ic = camel_imapx_command_new (
+				is, "FETCH", job->folder, job->cancellable,
+				"UID FETCH %t (BODY.PEEK[]", job->u.get_message.uid);
 			camel_imapx_command_add(ic, "<%u.%u>", job->u.get_message.fetch_offset, MULTI_SIZE);
 			camel_imapx_command_add(ic, ")");
 			ic->complete = imapx_command_fetch_message_done;
@@ -3199,7 +3279,7 @@ imapx_command_fetch_message_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 			if (stream) {
 				gchar *tmp = camel_data_cache_get_filename (ifolder->cache, "tmp", job->u.get_message.uid, NULL);
 
-				if (camel_stream_flush (stream, &job->error) == 0 && camel_stream_close (stream, &job->error) == 0) {
+				if (camel_stream_flush (stream, job->cancellable, &job->error) == 0 && camel_stream_close (stream, job->cancellable, &job->error) == 0) {
 					gchar *cache_file = camel_data_cache_get_filename  (ifolder->cache, "cur", job->u.get_message.uid, NULL);
 					gchar *temp = g_strrstr (cache_file, "/"), *dir;
 
@@ -3237,8 +3317,9 @@ imapx_job_get_message_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 
 	if (job->u.get_message.use_multi_fetch) {
 		for (i=0; i < 3 && job->u.get_message.fetch_offset < job->u.get_message.size;i++) {
-			ic = camel_imapx_command_new(is, "FETCH", job->folder,
-					"UID FETCH %t (BODY.PEEK[]", job->u.get_message.uid);
+			ic = camel_imapx_command_new (
+				is, "FETCH", job->folder, job->cancellable,
+				"UID FETCH %t (BODY.PEEK[]", job->u.get_message.uid);
 			camel_imapx_command_add(ic, "<%u.%u>", job->u.get_message.fetch_offset, MULTI_SIZE);
 			camel_imapx_command_add(ic, ")");
 			ic->complete = imapx_command_fetch_message_done;
@@ -3249,8 +3330,9 @@ imapx_job_get_message_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 			imapx_command_queue (is, ic);
 		}
 	} else {
-		ic = camel_imapx_command_new(is, "FETCH", job->folder,
-				"UID FETCH %t (BODY.PEEK[])", job->u.get_message.uid);
+		ic = camel_imapx_command_new (
+			is, "FETCH", job->folder, job->cancellable,
+			"UID FETCH %t (BODY.PEEK[])", job->u.get_message.uid);
 		ic->complete = imapx_command_fetch_message_done;
 		ic->job = job;
 		ic->pri = job->pri;
@@ -3262,13 +3344,16 @@ imapx_job_get_message_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 /* ********************************************************************** */
 
 static void
-imapx_command_copy_messages_step_start (CamelIMAPXServer *is, CamelIMAPXJob *job, gint index)
+imapx_command_copy_messages_step_start (CamelIMAPXServer *is,
+                                        CamelIMAPXJob *job, gint index)
 {
 	CamelIMAPXCommand *ic;
 	GPtrArray *uids = job->u.copy_messages.uids;
 	gint i = index;
 
-	ic = camel_imapx_command_new (is, "COPY", job->folder, "UID COPY ");
+	ic = camel_imapx_command_new (
+		is, "COPY", job->folder,
+		job->cancellable, "UID COPY ");
 	ic->complete = imapx_command_copy_messages_step_done;
 	ic->job = job;
 	ic->pri = job->pri;
@@ -3296,7 +3381,8 @@ imapx_command_copy_messages_step_start (CamelIMAPXServer *is, CamelIMAPXJob *job
 }
 
 static void
-imapx_command_copy_messages_step_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
+imapx_command_copy_messages_step_done (CamelIMAPXServer *is,
+                                       CamelIMAPXCommand *ic)
 {
 	CamelIMAPXJob *job = ic->job;
 	gint i = job->u.copy_messages.index;
@@ -3349,9 +3435,11 @@ cleanup:
 }
 
 static void
-imapx_job_copy_messages_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
+imapx_job_copy_messages_start (CamelIMAPXServer *is,
+                               CamelIMAPXJob *job)
 {
-	if (!imapx_server_sync_changes (is, job->folder, job->pri, &job->error))
+	if (!imapx_server_sync_changes (
+		is, job->folder, job->pri, job->cancellable, &job->error))
 		imapx_job_done (is, job);
 
 	g_ptr_array_sort (job->u.copy_messages.uids, (GCompareFunc) imapx_uids_array_cmp);
@@ -3362,7 +3450,8 @@ imapx_job_copy_messages_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 /* ********************************************************************** */
 
 static void
-imapx_command_append_message_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
+imapx_command_append_message_done (CamelIMAPXServer *is,
+                                   CamelIMAPXCommand *ic)
 {
 	CamelIMAPXJob *job = ic->job;
 	CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) job->folder;
@@ -3426,17 +3515,18 @@ imapx_command_append_message_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 }
 
 static void
-imapx_job_append_message_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
+imapx_job_append_message_start (CamelIMAPXServer *is,
+                                CamelIMAPXJob *job)
 {
 	CamelIMAPXCommand *ic;
 
 	/* TODO: we could supply the original append date from the file timestamp */
-	ic = camel_imapx_command_new(is, "APPEND", NULL,
-				     "APPEND %f %F %P",
-				     job->folder,
-				     ((CamelMessageInfoBase *)job->u.append_message.info)->flags,
-				     ((CamelMessageInfoBase *)job->u.append_message.info)->user_flags,
-				     job->u.append_message.path);
+	ic = camel_imapx_command_new (
+		is, "APPEND", NULL, job->cancellable,
+		"APPEND %f %F %P", job->folder,
+		((CamelMessageInfoBase *)job->u.append_message.info)->flags,
+		((CamelMessageInfoBase *)job->u.append_message.info)->user_flags,
+		job->u.append_message.path);
 	ic->complete = imapx_command_append_message_done;
 	ic->job = job;
 	ic->pri = job->pri;
@@ -3509,7 +3599,8 @@ imapx_index_next (GPtrArray *uids, CamelFolderSummary *s, guint index)
 }
 
 static void
-imapx_command_step_fetch_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
+imapx_command_step_fetch_done (CamelIMAPXServer *is,
+                               CamelIMAPXCommand *ic)
 {
 	CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *)ic->job->folder;
 	CamelIMAPXSummary *isum = (CamelIMAPXSummary *)ic->job->folder->summary;
@@ -3539,7 +3630,9 @@ imapx_command_step_fetch_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 	if (i<infos->len) {
 		camel_imapx_command_free (ic);
 
-		ic = camel_imapx_command_new(is, "FETCH", job->folder, "UID FETCH ");
+		ic = camel_imapx_command_new (
+			is, "FETCH", job->folder,
+			job->cancellable, "UID FETCH ");
 		ic->complete = imapx_command_step_fetch_done;
 		ic->job = job;
 		ic->pri = job->pri - 1;
@@ -3623,7 +3716,8 @@ imapx_uid_cmp (gconstpointer ap, gconstpointer bp, gpointer data)
 }
 
 static void
-imapx_job_scan_changes_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
+imapx_job_scan_changes_done (CamelIMAPXServer *is,
+                             CamelIMAPXCommand *ic)
 {
 	CamelIMAPXJob *job = ic->job;
 	gint i;
@@ -3754,7 +3848,8 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 		/* If we have any new messages, download their headers, but only a few (100?) at a time */
 		if (fetch_new) {
 			camel_operation_start (
-				job->op, _("Fetching summary information for new messages in %s"),
+				job->cancellable,
+				_("Fetching summary information for new messages in %s"),
 				camel_folder_get_name (job->folder));
 			imapx_uidset_init (&job->u.refresh_info.uidset, BATCH_FETCH_COUNT, 0);
 			/* These are new messages which arrived since we last knew the unseen count;
@@ -3789,16 +3884,19 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 }
 
 static void
-imapx_job_scan_changes_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
+imapx_job_scan_changes_start (CamelIMAPXServer *is,
+                              CamelIMAPXJob *job)
 {
 	CamelIMAPXCommand *ic;
 
 	camel_operation_start (
-		job->op, _("Scanning for changed messages in %s"),
+		job->cancellable,
+		_("Scanning for changed messages in %s"),
 		camel_folder_get_name (job->folder));
 
-	ic = camel_imapx_command_new (is, "FETCH", job->folder,
-				     "UID FETCH 1:* (UID FLAGS)");
+	ic = camel_imapx_command_new (
+		is, "FETCH", job->folder, job->cancellable,
+		"UID FETCH 1:* (UID FLAGS)");
 	ic->job = job;
 	ic->complete = imapx_job_scan_changes_done;
 	ic->pri = job->pri;
@@ -3807,7 +3905,8 @@ imapx_job_scan_changes_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 }
 
 static void
-imapx_command_fetch_new_messages_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
+imapx_command_fetch_new_messages_done (CamelIMAPXServer *is,
+                                       CamelIMAPXCommand *ic)
 {
 	CamelIMAPXSummary *isum = (CamelIMAPXSummary *)ic->job->folder->summary;
 	CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *)ic->job->folder;
@@ -3849,15 +3948,13 @@ imapx_command_fetch_new_messages_done (CamelIMAPXServer *is, CamelIMAPXCommand *
 exception:
 	camel_folder_change_info_free (ic->job->u.refresh_info.changes);
 
-	if (ic->job->op)
-		g_object_unref (ic->job->op);
-
 	imapx_job_done (is, ic->job);
 	camel_imapx_command_free (ic);
 }
 
 static void
-imapx_job_fetch_new_messages_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
+imapx_job_fetch_new_messages_start (CamelIMAPXServer *is,
+                                    CamelIMAPXJob *job)
 {
 	CamelIMAPXCommand *ic;
 	CamelFolder *folder = job->folder;
@@ -3878,19 +3975,22 @@ imapx_job_fetch_new_messages_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 		uid = g_strdup ("1");
 
 	camel_operation_start (
-		job->op, _("Fetching summary information for new messages in %s"),
+		job->cancellable,
+		_("Fetching summary information for new messages in %s"),
 		camel_folder_get_name (folder));
 
 	if (diff > BATCH_FETCH_COUNT) {
-		ic = camel_imapx_command_new (is, "FETCH", job->folder,
-				     "UID FETCH %s:* (UID FLAGS)", uid);
-		imapx_uidset_init (&job->u.refresh_info.uidset, BATCH_FETCH_COUNT, 0);
-		job->u.refresh_info.infos = g_array_new (0, 0, sizeof (struct _refresh_info));
+		ic = camel_imapx_command_new (
+			is, "FETCH", job->folder, job->cancellable,
+			"UID FETCH %s:* (UID FLAGS)", uid);
+		imapx_uidset_init(&job->u.refresh_info.uidset, BATCH_FETCH_COUNT, 0);
+		job->u.refresh_info.infos = g_array_new (0, 0, sizeof(struct _refresh_info));
 		ic->pri = job->pri;
 		ic->complete = imapx_command_step_fetch_done;
 	} else {
-		ic = camel_imapx_command_new (is, "FETCH", job->folder,
-					"UID FETCH %s:* (RFC822.SIZE RFC822.HEADER FLAGS)", uid);
+		ic = camel_imapx_command_new (
+			is, "FETCH", job->folder, job->cancellable,
+			"UID FETCH %s:* (RFC822.SIZE RFC822.HEADER FLAGS)", uid);
 		ic->pri = job->pri;
 		ic->complete = imapx_command_fetch_new_messages_done;
 	}
@@ -3901,7 +4001,8 @@ imapx_job_fetch_new_messages_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 }
 
 static void
-imapx_job_refresh_info_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
+imapx_job_refresh_info_start (CamelIMAPXServer *is,
+                              CamelIMAPXJob *job)
 {
 	guint32 total;
 	CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) job->folder;
@@ -3916,7 +4017,9 @@ imapx_job_refresh_info_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 
 	/* Sync changes first, else unread count will not
 	   match. Need to think about better ways for this */
-	if (!imapx_server_sync_changes (is, folder, job->pri, &job->error))
+	if (!imapx_server_sync_changes (
+		is, folder, job->pri,
+		job->cancellable, &job->error))
 		goto done;
 
 #if 0 /* There are issues with this still; continue with the buggy behaviour
@@ -3953,21 +4056,27 @@ imapx_job_refresh_info_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 					if (!imapx_stop_idle (is, &job->error))
 						goto done;
 				/* This doesn't work -- this is an immediate command, not queued */
-				if (!imapx_select (is, folder, TRUE, &job->error))
+				if (!imapx_select (
+					is, folder, TRUE,
+					job->cancellable, &job->error))
 					goto done;
 			} else {
 				/* Or maybe just NOOP, unless we're in IDLE in which case do nothing */
-				if (!imapx_idle_supported (is) || !imapx_in_idle (is)) {
-					if (!camel_imapx_server_noop (is, folder, &job->error))
+				if (!imapx_idle_supported(is) || !imapx_in_idle(is)) {
+					if (!camel_imapx_server_noop (is, folder, job->cancellable, &job->error))
 						goto done;
 				}
 			}
 		} else {
 			if (is->cinfo->capa & IMAPX_CAPABILITY_CONDSTORE)
-				ic = camel_imapx_command_new (is, "STATUS", NULL, "STATUS %f (MESSAGES UNSEEN UIDVALIDITY UIDNEXT HIGHESTMODSEQ)", folder);
+				ic = camel_imapx_command_new (
+					is, "STATUS", NULL, job->cancellable,
+					"STATUS %f (MESSAGES UNSEEN UIDVALIDITY UIDNEXT HIGHESTMODSEQ)", folder);
 			else
-				ic = camel_imapx_command_new (is, "STATUS", NULL, "STATUS %f (MESSAGES UNSEEN UIDVALIDITY UIDNEXT)", folder);
-
+				ic = camel_imapx_command_new (
+					is, "STATUS", NULL, job->cancellable,
+					"STATUS %f (MESSAGES UNSEEN UIDVALIDITY UIDNEXT)", folder);
+		
 			ic->job = job;
 			ic->pri = job->pri;
 
@@ -4013,7 +4122,9 @@ imapx_job_refresh_info_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 		if (!total)
 			need_rescan = FALSE;
 
-		if (!imapx_server_fetch_new_messages (is, folder, FALSE, FALSE, &job->error))
+		if (!imapx_server_fetch_new_messages (
+			is, folder, FALSE, FALSE,
+			job->cancellable, &job->error))
 			goto done;
 
 		/* If QRESYNC-capable we'll have got all flags changes in SELECT */
@@ -4026,7 +4137,7 @@ imapx_job_refresh_info_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 
 	if (can_qresync) {
 		/* Actually we only want to select it; no need for the NOOP */
-		camel_imapx_server_noop (is, folder, &job->error);
+		camel_imapx_server_noop (is, folder, job->cancellable, &job->error);
 	qresync_done:
 		isum->modseq = ifolder->modseq_on_server;
 		total = camel_folder_summary_count (job->folder->summary);
@@ -4056,7 +4167,8 @@ done:
 /* ********************************************************************** */
 
 static void
-imapx_command_expunge_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
+imapx_command_expunge_done (CamelIMAPXServer *is,
+                            CamelIMAPXCommand *ic)
 {
 	if (ic->error != NULL || ic->status->result != IMAPX_OK) {
 		if (ic->error == NULL)
@@ -4113,14 +4225,19 @@ imapx_command_expunge_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 }
 
 static void
-imapx_job_expunge_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
+imapx_job_expunge_start (CamelIMAPXServer *is,
+                         CamelIMAPXJob *job)
 {
 	CamelIMAPXCommand *ic;
 
-	imapx_server_sync_changes (is, job->folder, job->pri, &job->error);
+	imapx_server_sync_changes (
+		is, job->folder, job->pri,
+		job->cancellable, &job->error);
 
 	/* TODO handle UIDPLUS capability */
-	ic = camel_imapx_command_new(is, "EXPUNGE", job->folder, "EXPUNGE");
+	ic = camel_imapx_command_new (
+		is, "EXPUNGE", job->folder,
+		job->cancellable, "EXPUNGE");
 	ic->job = job;
 	ic->pri = job->pri;
 	ic->complete = imapx_command_expunge_done;
@@ -4130,7 +4247,8 @@ imapx_job_expunge_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 /* ********************************************************************** */
 
 static void
-imapx_command_list_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
+imapx_command_list_done (CamelIMAPXServer *is,
+                         CamelIMAPXCommand *ic)
 {
 	if (ic->error != NULL || ic->status->result != IMAPX_OK) {
 		if (ic->error == NULL)
@@ -4147,13 +4265,17 @@ imapx_command_list_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 }
 
 static void
-imapx_job_list_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
+imapx_job_list_start (CamelIMAPXServer *is,
+                      CamelIMAPXJob *job)
 {
 	CamelIMAPXCommand *ic;
 
-	ic = camel_imapx_command_new(is, "LIST", NULL, "%s \"\" %s",
-				     (job->u.list.flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)?"LSUB":"LIST",
-				     job->u.list.pattern);
+	ic = camel_imapx_command_new (
+		is, "LIST", NULL, job->cancellable,
+		"%s \"\" %s",
+		(job->u.list.flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED) ?
+			"LSUB" : "LIST",
+		job->u.list.pattern);
 	if (job->u.list.ext) {
 		/* Hm, we need a way to add atoms _without_ quoting or using literals */
 		camel_imapx_command_add(ic, " ");
@@ -4182,7 +4304,8 @@ imapx_encode_folder_name (CamelIMAPXStore *istore, const gchar *folder_name)
 }
 
 static void
-imapx_command_subscription_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
+imapx_command_subscription_done (CamelIMAPXServer *is,
+                                 CamelIMAPXCommand *ic)
 {
 	if (ic->error != NULL || ic->status->result != IMAPX_OK) {
 		if (ic->error == NULL)
@@ -4198,7 +4321,8 @@ imapx_command_subscription_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 }
 
 static void
-imapx_job_manage_subscription_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
+imapx_job_manage_subscription_start (CamelIMAPXServer *is,
+                                     CamelIMAPXJob *job)
 {
 	CamelIMAPXCommand *ic;
 	const gchar *str = NULL;
@@ -4209,8 +4333,12 @@ imapx_job_manage_subscription_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 	else
 		str = "UNSUBSCRIBE";
 
-	encoded_fname = imapx_encode_folder_name ((CamelIMAPXStore *) is->store, job->u.manage_subscriptions.folder_name);
-	ic = camel_imapx_command_new (is, str, NULL, "%s %s", str, encoded_fname);
+	encoded_fname = imapx_encode_folder_name (
+		(CamelIMAPXStore *) is->store,
+		job->u.manage_subscriptions.folder_name);
+	ic = camel_imapx_command_new (
+		is, str, NULL, job->cancellable,
+		"%s %s", str, encoded_fname);
 
 	ic->pri = job->pri;
 	ic->job = job;
@@ -4223,7 +4351,8 @@ imapx_job_manage_subscription_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 /* ********************************************************************** */
 
 static void
-imapx_command_create_folder_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
+imapx_command_create_folder_done (CamelIMAPXServer *is,
+                                  CamelIMAPXCommand *ic)
 {
 	if (ic->error != NULL || ic->status->result != IMAPX_OK) {
 		if (ic->error == NULL)
@@ -4239,13 +4368,16 @@ imapx_command_create_folder_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 }
 
 static void
-imapx_job_create_folder_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
+imapx_job_create_folder_start (CamelIMAPXServer *is,
+                               CamelIMAPXJob *job)
 {
 	CamelIMAPXCommand *ic;
 	gchar *encoded_fname = NULL;
 
 	encoded_fname = camel_utf8_utf7 (job->u.folder_name);
-	ic = camel_imapx_command_new (is, "CREATE", NULL, "CREATE %s", encoded_fname);
+	ic = camel_imapx_command_new (
+		is, "CREATE", NULL, job->cancellable,
+		"CREATE %s", encoded_fname);
 	ic->pri = job->pri;
 	ic->job = job;
 	ic->complete = imapx_command_create_folder_done;
@@ -4257,7 +4389,8 @@ imapx_job_create_folder_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 /* ********************************************************************** */
 
 static void
-imapx_command_delete_folder_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
+imapx_command_delete_folder_done (CamelIMAPXServer *is,
+                                  CamelIMAPXCommand *ic)
 {
 	if (ic->error != NULL || ic->status->result != IMAPX_OK) {
 		if (ic->error == NULL)
@@ -4273,17 +4406,21 @@ imapx_command_delete_folder_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 }
 
 static void
-imapx_job_delete_folder_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
+imapx_job_delete_folder_start (CamelIMAPXServer *is,
+                               CamelIMAPXJob *job)
 {
 	CamelIMAPXCommand *ic;
 	gchar *encoded_fname = NULL;
 
 	encoded_fname = imapx_encode_folder_name ((CamelIMAPXStore *) is->store, job->u.folder_name);
 
-	job->folder = camel_store_get_folder(is->store, "INBOX", 0, &job->error);
+	job->folder = camel_store_get_folder (
+		is->store, "INBOX", 0, job->cancellable, &job->error);
 
 	/* make sure to-be-deleted folder is not selected by selecting INBOX for this operation */
-	ic = camel_imapx_command_new (is, "DELETE", job->folder, "DELETE %s", encoded_fname);
+	ic = camel_imapx_command_new (
+		is, "DELETE", job->folder, job->cancellable,
+		"DELETE %s", encoded_fname);
 	ic->pri = job->pri;
 	ic->job = job;
 	ic->complete = imapx_command_delete_folder_done;
@@ -4295,7 +4432,8 @@ imapx_job_delete_folder_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 /* ********************************************************************** */
 
 static void
-imapx_command_rename_folder_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
+imapx_command_rename_folder_done (CamelIMAPXServer *is,
+                                  CamelIMAPXCommand *ic)
 {
 	if (ic->error != NULL || ic->status->result != IMAPX_OK) {
 		if (ic->error == NULL)
@@ -4311,17 +4449,21 @@ imapx_command_rename_folder_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 }
 
 static void
-imapx_job_rename_folder_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
+imapx_job_rename_folder_start (CamelIMAPXServer *is,
+                               CamelIMAPXJob *job)
 {
 	CamelIMAPXCommand *ic;
 	gchar *en_ofname = NULL, *en_nfname = NULL;
 
-	job->folder = camel_store_get_folder(is->store, "INBOX", 0, &job->error);
+	job->folder = camel_store_get_folder (
+		is->store, "INBOX", 0, job->cancellable, &job->error);
 
 	en_ofname = imapx_encode_folder_name ((CamelIMAPXStore *) is->store, job->u.rename_folder.ofolder_name);
 	en_nfname = imapx_encode_folder_name ((CamelIMAPXStore *) is->store, job->u.rename_folder.nfolder_name);
 
-	ic = camel_imapx_command_new (is, "RENAME", job->folder, "RENAME %s %s", en_ofname, en_nfname);
+	ic = camel_imapx_command_new (
+		is, "RENAME", job->folder, job->cancellable,
+		"RENAME %s %s", en_ofname, en_nfname);
 	ic->pri = job->pri;
 	ic->job = job;
 	ic->complete = imapx_command_rename_folder_done;
@@ -4334,7 +4476,8 @@ imapx_job_rename_folder_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 /* ********************************************************************** */
 
 static void
-imapx_command_noop_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
+imapx_command_noop_done (CamelIMAPXServer *is,
+                         CamelIMAPXCommand *ic)
 {
 	if (ic->error != NULL || ic->status->result != IMAPX_OK) {
 		if (ic->error == NULL)
@@ -4350,11 +4493,13 @@ imapx_command_noop_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 }
 
 static void
-imapx_job_noop_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
+imapx_job_noop_start (CamelIMAPXServer *is,
+                      CamelIMAPXJob *job)
 {
 	CamelIMAPXCommand *ic;
 
-	ic = camel_imapx_command_new (is, "NOOP", job->folder, "NOOP");
+	ic = camel_imapx_command_new (
+		is, "NOOP", job->folder, job->cancellable, "NOOP");
 
 	ic->job = job;
 	ic->complete = imapx_command_noop_done;
@@ -4512,7 +4657,9 @@ imapx_job_sync_changes_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 				if ( (on && (((flags ^ sflags) & flags) & flag))
 				     || (!on && (((flags ^ sflags) & ~flags) & flag))) {
 					if (ic == NULL) {
-						ic = camel_imapx_command_new(is, "STORE", job->folder, "UID STORE ");
+						ic = camel_imapx_command_new (
+							is, "STORE", job->folder,
+							job->cancellable, "UID STORE ");
 						ic->complete = imapx_command_sync_changes_done;
 						ic->job = job;
 						ic->pri = job->pri;
@@ -4548,7 +4695,9 @@ imapx_job_sync_changes_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 					CamelIMAPXMessageInfo *info = c->infos->pdata[i];
 
 					if (ic == NULL) {
-						ic = camel_imapx_command_new(is, "STORE", job->folder, "UID STORE ");
+						ic = camel_imapx_command_new (
+							is, "STORE", job->folder,
+							job->cancellable, "UID STORE ");
 						ic->complete = imapx_command_sync_changes_done;
 						ic->job = job;
 						ic->pri = job->pri;
@@ -4606,13 +4755,15 @@ cancel_all_jobs (CamelIMAPXServer *is, GError *error)
 /* ********************************************************************** */
 
 static void
-parse_contents (CamelIMAPXServer *is, GError **error)
+parse_contents (CamelIMAPXServer *is,
+                GCancellable *cancellable,
+                GError **error)
 {
 	gint buffered = 0;
 	GError *local_error = NULL;
 
 	do {
-		imapx_step (is, &local_error);
+		imapx_step (is, cancellable, &local_error);
 
 		buffered = camel_imapx_stream_buffered (is->stream);
 
@@ -4633,15 +4784,13 @@ static gpointer
 imapx_parser_thread (gpointer d)
 {
 	CamelIMAPXServer *is = d;
-	CamelOperation *op;
+	GCancellable *cancellable;
 	GError *local_error = NULL;
 
-	op = camel_operation_new ();
-	camel_operation_register (op);
-	is->op = op;
+	cancellable = g_object_ref (is->cancellable);
 
 	while (local_error == NULL && is->stream) {
-		camel_operation_uncancel (op);
+		g_cancellable_reset (cancellable);
 #ifndef G_OS_WIN32
 		if (is->is_process_stream)	{
 			GPollFD fds[2] = { {0, 0, 0}, {0, 0, 0} };
@@ -4649,7 +4798,7 @@ imapx_parser_thread (gpointer d)
 
 			fds[0].fd = ((CamelStreamProcess *)is->stream->source)->sockfd;
 			fds[0].events = G_IO_IN;
-			fds[1].fd = camel_operation_cancel_fd (op);
+			fds[1].fd = g_cancellable_get_fd (cancellable);
 			fds[1].events = G_IO_IN;
 			res = g_poll (fds, 2, 1000*30);
 			if (res == -1)
@@ -4657,9 +4806,10 @@ imapx_parser_thread (gpointer d)
 			else if (res == 0)
 				/* timed out */;
 			else if (fds[0].revents & G_IO_IN) {
-				parse_contents (is, &local_error);
+				parse_contents (is, cancellable, &local_error);
 			} else if (fds[1].revents & G_IO_IN)
 				errno = EINTR;
+			g_cancellable_release_fd (cancellable);
 		} else
 #endif
 		{
@@ -4668,7 +4818,7 @@ imapx_parser_thread (gpointer d)
 
 			pollfds[0].fd = camel_tcp_stream_get_file_desc (CAMEL_TCP_STREAM (is->stream->source));
 			pollfds[0].in_flags = PR_POLL_READ;
-			pollfds[1].fd = camel_operation_cancel_prfd (op);
+			pollfds[1].fd = camel_operation_cancel_prfd (CAMEL_OPERATION (cancellable));
 			pollfds[1].in_flags = PR_POLL_READ;
 
 #include <prio.h>
@@ -4679,7 +4829,7 @@ imapx_parser_thread (gpointer d)
 			else if (res == 0) {
 				/* timed out */
 			} else if ((pollfds[0].out_flags & PR_POLL_READ)) {
-				parse_contents (is, &local_error);
+				parse_contents (is, cancellable, &local_error);
 			} else if (pollfds[1].out_flags & PR_POLL_READ)
 				errno = EINTR;
 		}
@@ -4692,7 +4842,7 @@ imapx_parser_thread (gpointer d)
 			break;
 		}
 
-		if (camel_operation_cancel_check (op)) {
+		if (camel_operation_cancel_check (CAMEL_OPERATION (cancellable))) {
 			gint is_empty;
 
 			QUEUE_LOCK (is);
@@ -4700,7 +4850,7 @@ imapx_parser_thread (gpointer d)
 			QUEUE_UNLOCK (is);
 
 			if ((is_empty || (imapx_idle_supported (is) && imapx_in_idle (is))))
-				camel_operation_uncancel (op);
+				camel_operation_uncancel (CAMEL_OPERATION (cancellable));
 			else
 				g_set_error (
 					&local_error, G_IO_ERROR,
@@ -4717,11 +4867,7 @@ imapx_parser_thread (gpointer d)
 
 	g_clear_error (&local_error);
 
-	if (op) {
-		camel_operation_unregister ();
-		g_object_unref (op);
-	}
-	is->op = NULL;
+	g_object_unref (cancellable);
 
 	is->parser_thread = NULL;
 	is->parser_quit = FALSE;
@@ -4772,8 +4918,12 @@ imapx_server_dispose (GObject *object)
 	QUEUE_UNLOCK (server);
 
 	server->parser_quit = TRUE;
-	if (server->op)
-		camel_operation_cancel (server->op);
+
+	if (server->cancellable != NULL) {
+		g_cancellable_cancel (server->cancellable);
+		g_object_unref (server->cancellable);
+		server->cancellable = NULL;
+	}
 
 	if (server->parser_thread)
 		g_thread_join (server->parser_thread);
@@ -4873,7 +5023,7 @@ imapx_disconnect (CamelIMAPXServer *is)
 	g_static_rec_mutex_lock (&is->ostream_lock);
 
 	if (is->stream) {
-		if (camel_stream_close (is->stream->source, NULL) == -1)
+		if (camel_stream_close (is->stream->source, NULL, NULL) == -1)
 			ret = FALSE;
 
 		g_object_unref (CAMEL_OBJECT (is->stream));
@@ -4905,7 +5055,9 @@ imapx_disconnect (CamelIMAPXServer *is)
 
 /* Client commands */
 gboolean
-camel_imapx_server_connect (CamelIMAPXServer *is, GError **error)
+camel_imapx_server_connect (CamelIMAPXServer *is,
+                            GCancellable *cancellable,
+                            GError **error)
 {
 	gboolean success;
 
@@ -4918,7 +5070,7 @@ camel_imapx_server_connect (CamelIMAPXServer *is, GError **error)
 		return TRUE;
 
 	g_static_rec_mutex_lock (&is->ostream_lock);
-	success = imapx_reconnect (is, error);
+	success = imapx_reconnect (is, cancellable, error);
 	g_static_rec_mutex_unlock (&is->ostream_lock);
 
 	if (!success)
@@ -4929,7 +5081,12 @@ camel_imapx_server_connect (CamelIMAPXServer *is, GError **error)
 }
 
 static CamelStream *
-imapx_server_get_message (CamelIMAPXServer *is, CamelFolder *folder, CamelOperation *op, const gchar *uid, gint pri, GError **error)
+imapx_server_get_message (CamelIMAPXServer *is,
+                          CamelFolder *folder,
+                          const gchar *uid,
+                          gint pri,
+                          GCancellable *cancellable,
+                          GError **error)
 {
 	CamelStream *stream = NULL, *tmp_stream;
 	CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) folder;
@@ -4980,12 +5137,11 @@ imapx_server_get_message (CamelIMAPXServer *is, CamelFolder *folder, CamelOperat
 
 	tmp_stream = camel_data_cache_add (ifolder->cache, "tmp", uid, NULL);
 
-	job = g_malloc0 (sizeof (*job));
+	job = imapx_job_new (cancellable);
 	job->pri = pri;
 	job->type = IMAPX_JOB_GET_MESSAGE;
 	job->start = imapx_job_get_message_start;
 	job->folder = folder;
-	job->op = op;
 	job->u.get_message.uid = (gchar *)uid;
 	job->u.get_message.stream = tmp_stream;
 
@@ -5018,20 +5174,28 @@ imapx_server_get_message (CamelIMAPXServer *is, CamelFolder *folder, CamelOperat
 }
 
 CamelStream *
-camel_imapx_server_get_message (CamelIMAPXServer *is, CamelFolder *folder, const gchar *uid, GError **error)
+camel_imapx_server_get_message (CamelIMAPXServer *is,
+                                CamelFolder *folder,
+                                const gchar *uid,
+                                GCancellable *cancellable,
+                                GError **error)
 {
 	CamelStream *stream;
-	CamelOperation *op = camel_operation_registered ();
 
-	stream = imapx_server_get_message (is, folder, op, uid, IMAPX_PRIORITY_GET_MESSAGE, error);
-	if (op)
-		g_object_unref (op);
+	stream = imapx_server_get_message (
+		is, folder, uid,
+		IMAPX_PRIORITY_GET_MESSAGE,
+		cancellable, error);
 
 	return stream;
 }
 
 gboolean
-camel_imapx_server_sync_message (CamelIMAPXServer *is, CamelFolder *folder, const gchar *uid, GError **error)
+camel_imapx_server_sync_message (CamelIMAPXServer *is,
+                                 CamelFolder *folder,
+                                 const gchar *uid,
+                                 GCancellable *cancellable,
+                                 GError **error)
 {
 	gchar *cache_file = NULL;
 	CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) folder;
@@ -5043,7 +5207,10 @@ camel_imapx_server_sync_message (CamelIMAPXServer *is, CamelFolder *folder, cons
 		return TRUE;
 	}
 
-	stream = imapx_server_get_message (is, folder, NULL, uid, IMAPX_PRIORITY_SYNC_MESSAGE, error);
+	stream = imapx_server_get_message (
+		is, folder, uid,
+		IMAPX_PRIORITY_SYNC_MESSAGE,
+		cancellable, error);
 
 	if (stream == NULL)
 		return FALSE;
@@ -5054,11 +5221,17 @@ camel_imapx_server_sync_message (CamelIMAPXServer *is, CamelFolder *folder, cons
 }
 
 gboolean
-camel_imapx_server_copy_message (CamelIMAPXServer *is, CamelFolder *source, CamelFolder *dest, GPtrArray *uids, gboolean delete_originals, GError **error)
+camel_imapx_server_copy_message (CamelIMAPXServer *is,
+                                 CamelFolder *source,
+                                 CamelFolder *dest,
+                                 GPtrArray *uids,
+                                 gboolean delete_originals,
+                                 GCancellable *cancellable,
+                                 GError **error)
 {
 	CamelIMAPXJob *job;
 
-	job = g_malloc0 (sizeof (*job));
+	job = imapx_job_new (cancellable);
 	job->pri = IMAPX_PRIORITY_APPEND_MESSAGE;
 	job->type = IMAPX_JOB_COPY_MESSAGE;
 	job->start = imapx_job_copy_messages_start;
@@ -5074,7 +5247,12 @@ camel_imapx_server_copy_message (CamelIMAPXServer *is, CamelFolder *source, Came
 }
 
 gboolean
-camel_imapx_server_append_message (CamelIMAPXServer *is, CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *mi, GError **error)
+camel_imapx_server_append_message (CamelIMAPXServer *is,
+                                   CamelFolder *folder,
+                                   CamelMimeMessage *message,
+                                   const CamelMessageInfo *mi,
+                                   GCancellable *cancellable,
+                                   GError **error)
 {
 	gchar *uid = NULL, *tmp = NULL;
 	CamelStream *stream, *filter;
@@ -5108,7 +5286,7 @@ camel_imapx_server_append_message (CamelIMAPXServer *is, CamelFolder *folder, Ca
 	canon = camel_mime_filter_canon_new (CAMEL_MIME_FILTER_CANON_CRLF);
 	camel_stream_filter_add ((CamelStreamFilter *)filter, canon);
 	res = camel_data_wrapper_write_to_stream (
-		(CamelDataWrapper *)message, filter, error);
+		(CamelDataWrapper *)message, filter, cancellable, error);
 	g_object_unref (canon);
 	g_object_unref (filter);
 
@@ -5130,7 +5308,7 @@ camel_imapx_server_append_message (CamelIMAPXServer *is, CamelFolder *folder, Ca
 	   mechanism is used for normal uploading as well as
 	   offline re-syncing when we go back online */
 
-	job = g_malloc0 (sizeof (*job));
+	job = imapx_job_new (cancellable);
 	job->pri = IMAPX_PRIORITY_APPEND_MESSAGE;
 	job->type = IMAPX_JOB_APPEND_MESSAGE;
 	job->start = imapx_job_append_message_start;
@@ -5147,12 +5325,15 @@ camel_imapx_server_append_message (CamelIMAPXServer *is, CamelFolder *folder, Ca
 }
 
 gboolean
-camel_imapx_server_noop (CamelIMAPXServer *is, CamelFolder *folder, GError **error)
+camel_imapx_server_noop (CamelIMAPXServer *is,
+                         CamelFolder *folder,
+                         GCancellable *cancellable,
+                         GError **error)
 {
 	CamelIMAPXJob *job;
 	gboolean success;
 
-	job = g_malloc0 (sizeof (*job));
+	job = imapx_job_new (cancellable);
 	job->type = IMAPX_JOB_NOOP;
 	job->start = imapx_job_noop_start;
 	job->folder = folder;
@@ -5166,7 +5347,10 @@ camel_imapx_server_noop (CamelIMAPXServer *is, CamelFolder *folder, GError **err
 }
 
 gboolean
-camel_imapx_server_refresh_info (CamelIMAPXServer *is, CamelFolder *folder, GError **error)
+camel_imapx_server_refresh_info (CamelIMAPXServer *is,
+                                 CamelFolder *folder,
+                                 GCancellable *cancellable,
+                                 GError **error)
 {
 	CamelIMAPXJob *job;
 	gboolean registered = TRUE;
@@ -5182,12 +5366,11 @@ camel_imapx_server_refresh_info (CamelIMAPXServer *is, CamelFolder *folder, GErr
 		return TRUE;
 	}
 
-	job = g_malloc0 (sizeof (*job));
+	job = imapx_job_new (cancellable);
 	job->type = IMAPX_JOB_REFRESH_INFO;
 	job->start = imapx_job_refresh_info_start;
 	job->folder = folder;
-	job->op = camel_operation_registered ();
-	job->u.refresh_info.changes = camel_folder_change_info_new ();
+	job->u.refresh_info.changes = camel_folder_change_info_new();
 	job->pri = IMAPX_PRIORITY_REFRESH_INFO;
 
 	if (g_ascii_strcasecmp(full_name, "INBOX") == 0)
@@ -5204,8 +5387,8 @@ camel_imapx_server_refresh_info (CamelIMAPXServer *is, CamelFolder *folder, GErr
 
 	camel_folder_change_info_free (job->u.refresh_info.changes);
 
-	if (job->op)
-		g_object_unref (job->op);
+	if (job->cancellable)
+		g_object_unref (job->cancellable);
 	g_free (job);
 
 	return success;
@@ -5236,7 +5419,11 @@ imapx_sync_free_user (GArray *user_set)
 }
 
 static gboolean
-imapx_server_sync_changes (CamelIMAPXServer *is, CamelFolder *folder, gint pri, GError **error)
+imapx_server_sync_changes (CamelIMAPXServer *is,
+                           CamelFolder *folder,
+                           gint pri,
+                           GCancellable *cancellable,
+                           GError **error)
 {
 	guint i, on_orset, off_orset;
 	GPtrArray *uids;
@@ -5361,7 +5548,7 @@ imapx_server_sync_changes (CamelIMAPXServer *is, CamelFolder *folder, gint pri,
 		goto done;
 	}
 
-	job = g_malloc0 (sizeof (*job));
+	job = imapx_job_new (cancellable);
 	job->type = IMAPX_JOB_SYNC_CHANGES;
 	job->start = imapx_job_sync_changes_start;
 	job->pri = pri;
@@ -5390,14 +5577,22 @@ done:
 }
 
 gboolean
-camel_imapx_server_sync_changes (CamelIMAPXServer *is, CamelFolder *folder, GError **error)
+camel_imapx_server_sync_changes (CamelIMAPXServer *is,
+                                 CamelFolder *folder,
+                                 GCancellable *cancellable,
+                                 GError **error)
 {
-	return imapx_server_sync_changes (is, folder, IMAPX_PRIORITY_SYNC_CHANGES, error);
+	return imapx_server_sync_changes (
+		is, folder, IMAPX_PRIORITY_SYNC_CHANGES,
+		cancellable, error);
 }
 
 /* expunge-uids? */
 gboolean
-camel_imapx_server_expunge (CamelIMAPXServer *is, CamelFolder *folder, GError **error)
+camel_imapx_server_expunge (CamelIMAPXServer *is,
+                            CamelFolder *folder,
+                            GCancellable *cancellable,
+                            GError **error)
 {
 	CamelIMAPXJob *job;
 	gboolean registered;
@@ -5411,7 +5606,7 @@ camel_imapx_server_expunge (CamelIMAPXServer *is, CamelFolder *folder, GError **
 		return TRUE;
 	}
 
-	job = g_malloc0 (sizeof (*job));
+	job = imapx_job_new (cancellable);
 	job->type = IMAPX_JOB_EXPUNGE;
 	job->start = imapx_job_expunge_start;
 	job->pri = IMAPX_PRIORITY_EXPUNGE;
@@ -5471,6 +5666,7 @@ camel_imapx_server_list (CamelIMAPXServer *is,
                          const gchar *top,
                          guint32 flags,
                          const gchar *ext,
+                         GCancellable *cancellable,
                          GError **error)
 {
 	CamelIMAPXJob *job;
@@ -5479,7 +5675,7 @@ camel_imapx_server_list (CamelIMAPXServer *is,
 
 	encoded_name = camel_utf8_utf7 (top);
 
-	job = g_malloc0 (sizeof (*job));
+	job = imapx_job_new (cancellable);
 	job->type = IMAPX_JOB_LIST;
 	job->start = imapx_job_list_start;
 	job->pri = IMAPX_PRIORITY_LIST;
@@ -5510,12 +5706,16 @@ camel_imapx_server_list (CamelIMAPXServer *is,
 }
 
 gboolean
-camel_imapx_server_manage_subscription (CamelIMAPXServer *is, const gchar *folder_name, gboolean subscribe, GError **error)
+camel_imapx_server_manage_subscription (CamelIMAPXServer *is,
+                                        const gchar *folder_name,
+                                        gboolean subscribe,
+                                        GCancellable *cancellable,
+                                        GError **error)
 {
 	CamelIMAPXJob *job;
 	gboolean success;
 
-	job = g_malloc0 (sizeof (*job));
+	job = imapx_job_new (cancellable);
 	job->type = IMAPX_JOB_MANAGE_SUBSCRIPTION;
 	job->start = imapx_job_manage_subscription_start;
 	job->pri = IMAPX_PRIORITY_MANAGE_SUBSCRIPTION;
@@ -5530,12 +5730,15 @@ camel_imapx_server_manage_subscription (CamelIMAPXServer *is, const gchar *folde
 }
 
 gboolean
-camel_imapx_server_create_folder (CamelIMAPXServer *is, const gchar *folder_name, GError **error)
+camel_imapx_server_create_folder (CamelIMAPXServer *is,
+                                  const gchar *folder_name,
+                                  GCancellable *cancellable,
+                                  GError **error)
 {
 	CamelIMAPXJob *job;
 	gboolean success;
 
-	job = g_malloc0 (sizeof (*job));
+	job = imapx_job_new (cancellable);
 	job->type = IMAPX_JOB_CREATE_FOLDER;
 	job->start = imapx_job_create_folder_start;
 	job->pri = IMAPX_PRIORITY_CREATE_FOLDER;
@@ -5549,12 +5752,15 @@ camel_imapx_server_create_folder (CamelIMAPXServer *is, const gchar *folder_name
 }
 
 gboolean
-camel_imapx_server_delete_folder (CamelIMAPXServer *is, const gchar *folder_name, GError **error)
+camel_imapx_server_delete_folder (CamelIMAPXServer *is,
+                                  const gchar *folder_name,
+                                  GCancellable *cancellable,
+                                  GError **error)
 {
 	CamelIMAPXJob *job;
 	gboolean success;
 
-	job = g_malloc0 (sizeof (*job));
+	job = imapx_job_new (cancellable);
 	job->type = IMAPX_JOB_DELETE_FOLDER;
 	job->start = imapx_job_delete_folder_start;
 	job->pri = IMAPX_PRIORITY_DELETE_FOLDER;
@@ -5568,12 +5774,16 @@ camel_imapx_server_delete_folder (CamelIMAPXServer *is, const gchar *folder_name
 }
 
 gboolean
-camel_imapx_server_rename_folder (CamelIMAPXServer *is, const gchar *old_name, const gchar *new_name, GError **error)
+camel_imapx_server_rename_folder (CamelIMAPXServer *is,
+                                  const gchar *old_name,
+                                  const gchar *new_name,
+                                  GCancellable *cancellable,
+                                  GError **error)
 {
 	CamelIMAPXJob *job;
 	gboolean success;
 
-	job = g_malloc0 (sizeof (*job));
+	job = imapx_job_new (cancellable);
 	job->type = IMAPX_JOB_RENAME_FOLDER;
 	job->start = imapx_job_rename_folder_start;
 	job->pri = IMAPX_PRIORITY_RENAME_FOLDER;
diff --git a/camel/providers/imapx/camel-imapx-server.h b/camel/providers/imapx/camel-imapx-server.h
index 9ef6b6c..340eb6a 100644
--- a/camel/providers/imapx/camel-imapx-server.h
+++ b/camel/providers/imapx/camel-imapx-server.h
@@ -110,7 +110,7 @@ struct _CamelIMAPXServer {
 	   commands. Input stream does not require a lock since only parser_thread can operate on it */
 	GStaticRecMutex ostream_lock;
 	/* Used for canceling operations as well as signaling parser thread to disconnnect/quit */
-	CamelOperation *op;
+	GCancellable *cancellable;
 	gboolean parser_quit;
 
 	/* Idle */
@@ -138,60 +138,75 @@ CamelIMAPXServer *
 		camel_imapx_server_new		(CamelStore *store,
 						 CamelURL *url);
 gboolean	camel_imapx_server_connect	(CamelIMAPXServer *is,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	imapx_connect_to_server		(CamelIMAPXServer *is,
+						 GCancellable *cancellable,
 						 GError **error);
 GPtrArray *	camel_imapx_server_list		(CamelIMAPXServer *is,
 						 const gchar *top,
 						 guint32 flags,
 						 const gchar *ext,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_imapx_server_refresh_info	(CamelIMAPXServer *is,
 						 CamelFolder *folder,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_imapx_server_sync_changes	(CamelIMAPXServer *is,
 						 CamelFolder *folder,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_imapx_server_expunge	(CamelIMAPXServer *is,
 						 CamelFolder *folder,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_imapx_server_noop		(CamelIMAPXServer *is,
 						 CamelFolder *folder,
+						 GCancellable *cancellable,
 						 GError **error);
 CamelStream *	camel_imapx_server_get_message	(CamelIMAPXServer *is,
 						 CamelFolder *folder,
 						 const gchar *uid,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_imapx_server_copy_message	(CamelIMAPXServer *is,
 						 CamelFolder *source,
 						 CamelFolder *dest,
 						 GPtrArray *uids,
 						 gboolean delete_originals,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_imapx_server_append_message
 						(CamelIMAPXServer *is,
 						 CamelFolder *folder,
 						 CamelMimeMessage *message,
 						 const CamelMessageInfo *mi,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_imapx_server_sync_message (CamelIMAPXServer *is,
 						 CamelFolder *folder,
 						 const gchar *uid,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_imapx_server_manage_subscription
 						(CamelIMAPXServer *is,
 						 const gchar *folder_name,
 						 gboolean subscribe,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_imapx_server_create_folder (CamelIMAPXServer *is,
 						 const gchar *folder_name,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_imapx_server_delete_folder (CamelIMAPXServer *is,
 						 const gchar *folder_name,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_imapx_server_rename_folder (CamelIMAPXServer *is,
 						 const gchar *old_name,
 						 const gchar *new_name,
+						 GCancellable *cancellable,
 						 GError **error);
 struct _IMAPXJobQueueInfo *
 		camel_imapx_server_get_job_queue_info
diff --git a/camel/providers/imapx/camel-imapx-store.c b/camel/providers/imapx/camel-imapx-store.c
index dd7621a..b29ebc2 100644
--- a/camel/providers/imapx/camel-imapx-store.c
+++ b/camel/providers/imapx/camel-imapx-store.c
@@ -178,7 +178,9 @@ imapx_construct (CamelService *service, CamelSession *session, CamelProvider *pr
 extern CamelServiceAuthType camel_imapx_password_authtype;
 
 static GList *
-imapx_query_auth_types (CamelService *service, GError **error)
+imapx_query_auth_types (CamelService *service,
+                        GCancellable *cancellable,
+                        GError **error)
 {
 	CamelIMAPXStore *istore = CAMEL_IMAPX_STORE (service);
 	CamelServiceAuthType *authtype;
@@ -200,7 +202,7 @@ imapx_query_auth_types (CamelService *service, GError **error)
 
 	connected = server->stream != NULL;
 	if (!connected)
-		connected = imapx_connect_to_server (server, error);
+		connected = imapx_connect_to_server (server, cancellable, error);
 	camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
 	if (!connected)
 		return NULL;
@@ -232,7 +234,10 @@ imapx_get_name (CamelService *service, gboolean brief)
 }
 
 CamelIMAPXServer *
-camel_imapx_store_get_server (CamelIMAPXStore *istore, const gchar *folder_name, GError **error)
+camel_imapx_store_get_server (CamelIMAPXStore *istore,
+                              const gchar *folder_name,
+                              GCancellable *cancellable,
+                              GError **error)
 {
 	CamelIMAPXServer *server = NULL;
 
@@ -243,7 +248,7 @@ camel_imapx_store_get_server (CamelIMAPXStore *istore, const gchar *folder_name,
 	}
 	camel_service_lock (CAMEL_SERVICE (istore), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
-	server = camel_imapx_conn_manager_get_connection (istore->con_man, folder_name, error);
+	server = camel_imapx_conn_manager_get_connection (istore->con_man, folder_name, cancellable, error);
 
 	camel_service_unlock (CAMEL_SERVICE (istore), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
@@ -259,12 +264,14 @@ camel_imapx_store_op_done (CamelIMAPXStore *istore, CamelIMAPXServer *server, co
 }
 
 static gboolean
-imapx_connect (CamelService *service, GError **error)
+imapx_connect (CamelService *service,
+               GCancellable *cancellable,
+               GError **error)
 {
 	CamelIMAPXStore *istore = (CamelIMAPXStore *)service;
 	CamelIMAPXServer *server;
 
-	server = camel_imapx_store_get_server (istore, NULL, error);
+	server = camel_imapx_store_get_server (istore, NULL, cancellable, error);
 	if (server) {
 		g_object_unref (server);
 		return TRUE;
@@ -274,13 +281,16 @@ imapx_connect (CamelService *service, GError **error)
 }
 
 static gboolean
-imapx_disconnect (CamelService *service, gboolean clean, GError **error)
+imapx_disconnect (CamelService *service,
+                  gboolean clean,
+                  GCancellable *cancellable,
+                  GError **error)
 {
 	CamelIMAPXStore *istore = CAMEL_IMAPX_STORE (service);
 	CamelServiceClass *service_class;
 
 	service_class = CAMEL_SERVICE_CLASS (camel_imapx_store_parent_class);
-	if (!service_class->disconnect (service, clean, error))
+	if (!service_class->disconnect (service, clean, cancellable, error))
 		return FALSE;
 
 	camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
@@ -295,13 +305,15 @@ imapx_disconnect (CamelService *service, gboolean clean, GError **error)
 }
 
 static CamelFolder *
-imapx_get_junk (CamelStore *store, GError **error)
+imapx_get_junk (CamelStore *store,
+                GCancellable *cancellable,
+                GError **error)
 {
 	CamelFolder *folder;
 	CamelStoreClass *store_class;
 
 	store_class = CAMEL_STORE_CLASS (camel_imapx_store_parent_class);
-	folder = store_class->get_junk (store, error);
+	folder = store_class->get_junk (store, cancellable, error);
 
 	if (folder) {
 		CamelObject *object = CAMEL_OBJECT (folder);
@@ -317,13 +329,15 @@ imapx_get_junk (CamelStore *store, GError **error)
 }
 
 static CamelFolder *
-imapx_get_trash (CamelStore *store, GError **error)
+imapx_get_trash (CamelStore *store,
+                 GCancellable *cancellable,
+                 GError **error)
 {
 	CamelFolder *folder;
 	CamelStoreClass *store_class;
 
 	store_class = CAMEL_STORE_CLASS (camel_imapx_store_parent_class);
-	folder = store_class->get_trash (store, error);
+	folder = store_class->get_trash (store, cancellable, error);
 
 	if (folder) {
 		CamelObject *object = CAMEL_OBJECT (folder);
@@ -339,7 +353,9 @@ imapx_get_trash (CamelStore *store, GError **error)
 }
 
 static gboolean
-imapx_noop (CamelStore *store, GError **error)
+imapx_noop (CamelStore *store,
+            GCancellable *cancellable,
+            GError **error)
 {
 	CamelIMAPXStore *istore = (CamelIMAPXStore *) store;
 	GSList *servers = NULL, *l;
@@ -354,7 +370,7 @@ imapx_noop (CamelStore *store, GError **error)
 		CamelIMAPXServer *server = CAMEL_IMAPX_SERVER (l->data);
 
 		/* we just return last noops value, technically not correct though */
-		success = camel_imapx_server_noop (server, NULL, error);
+		success = camel_imapx_server_noop (server, NULL, cancellable, error);
 		g_object_unref (server);
 	}
 
@@ -425,7 +441,11 @@ get_folder_offline (CamelStore *store, const gchar *folder_name,
 }
 
 static CamelFolder *
-imapx_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError **error)
+imapx_get_folder (CamelStore *store,
+                  const gchar *folder_name,
+                  guint32 flags,
+                  GCancellable *cancellable,
+                  GError **error)
 {
 	CamelFolder *folder;
 
@@ -610,7 +630,11 @@ imapx_mark_folder_subscribed (CamelIMAPXStore *istore, const gchar *folder_name,
 }
 
 static gboolean
-imapx_subscribe_folder (CamelStore *store, const gchar *folder_name, gboolean emit_signal, GError **error)
+imapx_subscribe_folder (CamelStore *store,
+                        const gchar *folder_name,
+                        gboolean emit_signal,
+                        GCancellable *cancellable,
+                        GError **error)
 {
 	CamelIMAPXStore *istore = (CamelIMAPXStore *) store;
 	CamelIMAPXServer *server;
@@ -619,12 +643,13 @@ imapx_subscribe_folder (CamelStore *store, const gchar *folder_name, gboolean em
 	if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
 		return TRUE;
 
-	server = camel_imapx_store_get_server (istore, NULL, error);
+	server = camel_imapx_store_get_server (istore, NULL, cancellable, error);
 	if (!server)
 		return FALSE;
 
-	success = camel_imapx_server_manage_subscription (server, folder_name, TRUE, error);
-	g_object_unref (server);
+	success = camel_imapx_server_manage_subscription (
+		server, folder_name, TRUE, cancellable, error);
+	g_object_unref(server);
 
 	if (success)
 		imapx_mark_folder_subscribed (istore, folder_name, emit_signal);
@@ -633,7 +658,11 @@ imapx_subscribe_folder (CamelStore *store, const gchar *folder_name, gboolean em
 }
 
 static gboolean
-imapx_unsubscribe_folder (CamelStore *store, const gchar *folder_name, gboolean emit_signal, GError **error)
+imapx_unsubscribe_folder (CamelStore *store,
+                          const gchar *folder_name,
+                          gboolean emit_signal,
+                          GCancellable *cancellable,
+                          GError **error)
 {
 	CamelIMAPXStore *istore = (CamelIMAPXStore *) store;
 	CamelIMAPXServer *server;
@@ -642,12 +671,13 @@ imapx_unsubscribe_folder (CamelStore *store, const gchar *folder_name, gboolean
 	if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
 		return TRUE;
 
-	server = camel_imapx_store_get_server (istore, NULL, error);
+	server = camel_imapx_store_get_server (istore, NULL, cancellable, error);
 	if (!server)
 		return FALSE;
 
-	success = camel_imapx_server_manage_subscription (server, folder_name, FALSE, error);
-	g_object_unref (server);
+	success = camel_imapx_server_manage_subscription (
+		server, folder_name, FALSE, cancellable, error);
+	g_object_unref(server);
 
 	if (success)
 		imapx_unmark_folder_subscribed (istore, folder_name, emit_signal);
@@ -656,15 +686,23 @@ imapx_unsubscribe_folder (CamelStore *store, const gchar *folder_name, gboolean
 }
 
 static gboolean
-imapx_store_subscribe_folder (CamelStore *store, const gchar *folder_name, GError **error)
+imapx_store_subscribe_folder (CamelStore *store,
+                              const gchar *folder_name,
+                              GCancellable *cancellable,
+                              GError **error)
 {
-	return imapx_subscribe_folder (store, folder_name, TRUE, error);
+	return imapx_subscribe_folder (
+		store, folder_name, TRUE, cancellable, error);
 }
 
 static gboolean
-imapx_store_unsubscribe_folder (CamelStore *store, const gchar *folder_name, GError **error)
+imapx_store_unsubscribe_folder (CamelStore *store,
+                                const gchar *folder_name,
+                                GCancellable *cancellable,
+                                GError **error)
 {
-	return imapx_unsubscribe_folder (store, folder_name, TRUE, error);
+	return imapx_unsubscribe_folder (
+		store, folder_name, TRUE, cancellable, error);
 }
 
 static void
@@ -707,7 +745,10 @@ imapx_delete_folder_from_cache (CamelIMAPXStore *istore, const gchar *folder_nam
 }
 
 static gboolean
-imapx_delete_folder (CamelStore *store, const gchar *folder_name, GError **error)
+imapx_delete_folder (CamelStore *store,
+                     const gchar *folder_name,
+                     GCancellable *cancellable,
+                     GError **error)
 {
 	CamelIMAPXStore *istore = (CamelIMAPXStore *) store;
 	CamelIMAPXServer *server;
@@ -722,11 +763,12 @@ imapx_delete_folder (CamelStore *store, const gchar *folder_name, GError **error
 	}
 	/* Use INBOX connection as the implementation would try to select inbox to ensure
 	   we are not selected on the folder being deleted */
-	server = camel_imapx_store_get_server (istore, "INBOX", error);
+	server = camel_imapx_store_get_server (istore, "INBOX", cancellable, error);
 	if (!server)
 		return FALSE;
 
-	success = camel_imapx_server_delete_folder (server, folder_name, error);
+	success = camel_imapx_server_delete_folder (
+		server, folder_name, cancellable, error);
 	g_object_unref (server);
 
 	if (success)
@@ -769,7 +811,11 @@ rename_folder_info (CamelIMAPXStore *istore, const gchar *old_name, const gchar
 }
 
 static gboolean
-imapx_rename_folder (CamelStore *store, const gchar *old, const gchar *new, GError **error)
+imapx_rename_folder (CamelStore *store,
+                     const gchar *old,
+                     const gchar *new,
+                     GCancellable *cancellable,
+                     GError **error)
 {
 	CamelIMAPXStore *istore = (CamelIMAPXStore *) store;
 	CamelIMAPXServer *server;
@@ -785,18 +831,19 @@ imapx_rename_folder (CamelStore *store, const gchar *old, const gchar *new, GErr
 	}
 
 	if (istore->rec_options & IMAPX_SUBSCRIPTIONS)
-		imapx_unsubscribe_folder (store, old, FALSE, NULL);
+		imapx_unsubscribe_folder (store, old, FALSE, cancellable, NULL);
 
 	/* Use INBOX connection as the implementation would try to select inbox to ensure
 	   we are not selected on the folder being renamed */
-	server = camel_imapx_store_get_server(istore, "INBOX", error);
+	server = camel_imapx_store_get_server(istore, "INBOX", cancellable, error);
 	if (server) {
-		success = camel_imapx_server_rename_folder (server, old, new, error);
+		success = camel_imapx_server_rename_folder (
+			server, old, new, cancellable, error);
 		g_object_unref (server);
 	}
 
 	if (!success) {
-		imapx_subscribe_folder (store, old, FALSE, NULL);
+		imapx_subscribe_folder (store, old, FALSE, cancellable, NULL);
 		return FALSE;
 	}
 
@@ -804,7 +851,8 @@ imapx_rename_folder (CamelStore *store, const gchar *old, const gchar *new, GErr
 	rename_folder_info (istore, old, new);
 
 	if (istore->rec_options & IMAPX_SUBSCRIPTIONS)
-		success = imapx_subscribe_folder (store, new, FALSE, error);
+		success = imapx_subscribe_folder (
+			store, new, FALSE, cancellable, error);
 
 	storage_path = g_strdup_printf("%s/folders", istore->storage_path);
 	oldpath = imapx_path_to_physical (storage_path, old);
@@ -824,7 +872,11 @@ imapx_rename_folder (CamelStore *store, const gchar *old, const gchar *new, GErr
 }
 
 static CamelFolderInfo *
-imapx_create_folder (CamelStore *store, const gchar *parent_name, const gchar *folder_name, GError **error)
+imapx_create_folder (CamelStore *store,
+                     const gchar *parent_name,
+                     const gchar *folder_name,
+                     GCancellable *cancellable,
+                     GError **error)
 {
 	CamelStoreInfo *si;
 	CamelIMAPXStoreNamespace *ns;
@@ -843,7 +895,7 @@ imapx_create_folder (CamelStore *store, const gchar *parent_name, const gchar *f
 		return NULL;
 	}
 
-	server = camel_imapx_store_get_server (istore, NULL, error);
+	server = camel_imapx_store_get_server (istore, NULL, cancellable, error);
 	if (!server)
 		return NULL;
 
@@ -893,7 +945,8 @@ imapx_create_folder (CamelStore *store, const gchar *parent_name, const gchar *f
 	full_name = imapx_concat (istore, parent_real, real_name);
 	g_free (real_name);
 
-	success = camel_imapx_server_create_folder (server, full_name, error);
+	success = camel_imapx_server_create_folder (
+		server, full_name, cancellable, error);
 	g_object_unref (server);
 
 	if (success) {
@@ -1110,11 +1163,13 @@ fetch_folders_for_pattern (CamelIMAPXStore *istore,
                            guint32 flags,
                            const gchar *ext,
                            GHashTable *table,
+                           GCancellable *cancellable,
                            GError **error)
 {
 	GPtrArray *folders;
 
-	folders = camel_imapx_server_list (server, pattern, flags, ext, error);
+	folders = camel_imapx_server_list (
+		server, pattern, flags, ext, cancellable, error);
 	if (folders == NULL)
 		return FALSE;
 
@@ -1145,13 +1200,17 @@ get_namespaces (CamelIMAPXStore *istore)
 }
 
 static GHashTable *
-fetch_folders_for_namespaces (CamelIMAPXStore *istore, const gchar *pattern, gboolean sync, GError **error)
+fetch_folders_for_namespaces (CamelIMAPXStore *istore,
+                              const gchar *pattern,
+                              gboolean sync,
+                              GCancellable *cancellable,
+                              GError **error)
 {
 	CamelIMAPXServer *server;
 	GHashTable *folders = NULL;
 	GSList *namespaces = NULL, *l;
 
-	server = camel_imapx_store_get_server (istore, NULL, error);
+	server = camel_imapx_store_get_server (istore, NULL, cancellable, error);
 	if (!server)
 		return NULL;
 
@@ -1182,7 +1241,9 @@ fetch_folders_for_namespaces (CamelIMAPXStore *istore, const gchar *pattern, gbo
 				list_ext = "RETURN (SUBSCRIBED)";
 
 			flags |= CAMEL_STORE_FOLDER_INFO_RECURSIVE;
-			if (!fetch_folders_for_pattern (istore, server, pat, flags, list_ext, folders, error)) {
+			if (!fetch_folders_for_pattern (
+				istore, server, pat, flags, list_ext,
+				folders, cancellable, error)) {
 				g_free (pat);
 				goto exception;
 			}
@@ -1190,7 +1251,9 @@ fetch_folders_for_namespaces (CamelIMAPXStore *istore, const gchar *pattern, gbo
 				/* If the server doesn't support LIST-EXTENDED then we have to
 				   issue LSUB to list the subscribed folders separately */
 				flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
-				if (!fetch_folders_for_pattern (istore, server, pat, flags, NULL, folders, error)) {
+				if (!fetch_folders_for_pattern (
+					istore, server, pat, flags, NULL,
+					folders, cancellable, error)) {
 					g_free (pat);
 					goto exception;
 				}
@@ -1214,12 +1277,17 @@ exception:
 }
 
 static gboolean
-sync_folders (CamelIMAPXStore *istore, const gchar *pattern, gboolean sync, GError **error)
+sync_folders (CamelIMAPXStore *istore,
+              const gchar *pattern,
+              gboolean sync,
+              GCancellable *cancellable,
+              GError **error)
 {
 	GHashTable *folders_from_server;
 	gint i, total;
 
-	folders_from_server = fetch_folders_for_namespaces (istore, pattern, sync, error);
+	folders_from_server = fetch_folders_for_namespaces (
+		istore, pattern, sync, cancellable, error);
 	if (folders_from_server == NULL)
 		return FALSE;
 
@@ -1274,9 +1342,7 @@ sync_folders (CamelIMAPXStore *istore, const gchar *pattern, gboolean sync, GErr
 
 struct _imapx_refresh_msg {
 	CamelSessionThreadMsg msg;
-
 	CamelStore *store;
-	GError *error;
 };
 
 static void
@@ -1288,11 +1354,11 @@ imapx_refresh_finfo (CamelSession *session, CamelSessionThreadMsg *msg)
 	if (CAMEL_OFFLINE_STORE (istore)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
 		return;
 
-	if (!camel_service_connect ((CamelService *)istore, &m->error))
+	if (!camel_service_connect ((CamelService *)istore, &msg->error))
 		return;
 
 	/* look in all namespaces */
-	sync_folders (istore, "", FALSE, &m->error);
+	sync_folders (istore, "", FALSE, msg->cancellable, &msg->error);
 	camel_store_summary_save ((CamelStoreSummary *)istore->summary);
 }
 
@@ -1302,7 +1368,6 @@ imapx_refresh_free (CamelSession *session, CamelSessionThreadMsg *msg)
 	struct _imapx_refresh_msg *m = (struct _imapx_refresh_msg *)msg;
 
 	g_object_unref (m->store);
-	g_clear_error (&m->error);
 }
 
 static CamelSessionThreadOps imapx_refresh_ops = {
@@ -1311,15 +1376,16 @@ static CamelSessionThreadOps imapx_refresh_ops = {
 };
 
 static void
-discover_inbox (CamelStore *store)
+discover_inbox (CamelStore *store,
+                GCancellable *cancellable)
 {
 	CamelStoreInfo *si;
 	CamelIMAPXStore *istore = (CamelIMAPXStore *)store;
 
 	si = camel_store_summary_path((CamelStoreSummary *) istore->summary, "INBOX");
 	if (si == NULL || (si->flags & CAMEL_FOLDER_SUBSCRIBED) == 0) {
-		if (imapx_subscribe_folder (store, "INBOX", FALSE, NULL) && !si)
-			sync_folders (istore, "INBOX", TRUE, NULL);
+		if (imapx_subscribe_folder (store, "INBOX", FALSE, cancellable, NULL) && !si)
+			sync_folders (istore, "INBOX", TRUE, cancellable, NULL);
 
 		if (si)
 			camel_store_summary_info_free ((CamelStoreSummary *) istore->summary, si);
@@ -1327,7 +1393,11 @@ discover_inbox (CamelStore *store)
 }
 
 static CamelFolderInfo *
-imapx_get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GError **error)
+imapx_get_folder_info (CamelStore *store,
+                       const gchar *top,
+                       guint32 flags,
+                       GCancellable *cancellable,
+                       GError **error)
 {
 	CamelIMAPXStore *istore = (CamelIMAPXStore *)store;
 	CamelFolderInfo * fi= NULL;
@@ -1358,7 +1428,7 @@ imapx_get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GErro
 			istore->last_refresh_time = time (NULL);
 			m = camel_session_thread_msg_new (((CamelService *)store)->session, &imapx_refresh_ops, sizeof (*m));
 			m->store = g_object_ref (store);
-			camel_session_thread_queue (((CamelService *)store)->session, &m->msg, 0);
+			camel_session_thread_queue(((CamelService *)store)->session, &m->msg, 0);
 		}
 
 		fi = get_folder_info_offline (store, top, flags, error);
@@ -1394,7 +1464,7 @@ imapx_get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GErro
 		pattern[0] = '\0';
 	}
 
-	if (!sync_folders (istore, pattern, TRUE, error)) {
+	if (!sync_folders (istore, pattern, TRUE, cancellable, error)) {
 		g_mutex_unlock (istore->get_finfo_lock);
 		return NULL;
 	}
@@ -1403,7 +1473,7 @@ imapx_get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GErro
 
 	/* ensure the INBOX is subscribed if lsub was preferred*/
 	if (initial_setup && istore->rec_options & IMAPX_SUBSCRIPTIONS)
-		discover_inbox (store);
+		discover_inbox (store, cancellable);
 
 	fi = get_folder_info_offline (store, top, flags, error);
 	g_mutex_unlock (istore->get_finfo_lock);
diff --git a/camel/providers/imapx/camel-imapx-store.h b/camel/providers/imapx/camel-imapx-store.h
index e4853d6..be5ce65 100644
--- a/camel/providers/imapx/camel-imapx-store.h
+++ b/camel/providers/imapx/camel-imapx-store.h
@@ -95,6 +95,7 @@ struct _CamelIMAPXStoreClass {
 GType			camel_imapx_store_get_type	(void);
 CamelIMAPXServer *	camel_imapx_store_get_server	(CamelIMAPXStore *store,
 							const gchar *folder_name,
+							GCancellable *cancellable,
 							GError **error);
 void			camel_imapx_store_op_done	(CamelIMAPXStore *istore,
 							CamelIMAPXServer *server,
diff --git a/camel/providers/imapx/camel-imapx-stream.c b/camel/providers/imapx/camel-imapx-stream.c
index 94d629f..c87a88f 100644
--- a/camel/providers/imapx/camel-imapx-stream.c
+++ b/camel/providers/imapx/camel-imapx-stream.c
@@ -41,6 +41,7 @@ G_DEFINE_TYPE (CamelIMAPXStream, camel_imapx_stream, CAMEL_TYPE_STREAM)
 
 static gint
 imapx_stream_fill (CamelIMAPXStream *is,
+                   GCancellable *cancellable,
                    GError **error)
 {
 	gint left = 0;
@@ -52,7 +53,8 @@ imapx_stream_fill (CamelIMAPXStream *is,
 		is->ptr = is->buf;
 		left = camel_stream_read (
 			is->source, (gchar *) is->end,
-			is->bufsize - (is->end - is->buf), error);
+			is->bufsize - (is->end - is->buf),
+			cancellable, error);
 		if (left > 0) {
 			is->end += left;
 			io(is->tagprefix, "camel_imapx_read: buffer is '%.*s'\n", (gint)(is->end - is->ptr), is->ptr);
@@ -108,6 +110,7 @@ static gssize
 imapx_stream_read (CamelStream *stream,
                    gchar *buffer,
                    gsize n,
+                   GCancellable *cancellable,
                    GError **error)
 {
 	CamelIMAPXStream *is = (CamelIMAPXStream *)stream;
@@ -124,7 +127,7 @@ imapx_stream_read (CamelStream *stream,
 		is->ptr += max;
 	} else {
 		max = MIN (is->literal, n);
-		max = camel_stream_read (is->source, buffer, max, error);
+		max = camel_stream_read (is->source, buffer, max, cancellable, error);
 		if (max <= 0)
 			return max;
 	}
@@ -140,17 +143,19 @@ static gssize
 imapx_stream_write (CamelStream *stream,
                     const gchar *buffer,
                     gsize n,
+                    GCancellable *cancellable,
                     GError **error)
 {
 	CamelIMAPXStream *is = (CamelIMAPXStream *)stream;
 
 	io(is->tagprefix, "camel_imapx_write: '%.*s'\n", (gint)n, buffer);
 
-	return camel_stream_write (is->source, buffer, n, error);
+	return camel_stream_write (is->source, buffer, n, cancellable, error);
 }
 
 static gint
 imapx_stream_close (CamelStream *stream,
+                    GCancellable *cancellable,
                     GError **error)
 {
 	/* nop? */
@@ -159,6 +164,7 @@ imapx_stream_close (CamelStream *stream,
 
 static gint
 imapx_stream_flush (CamelStream *stream,
+                    GCancellable *cancellable,
                     GError **error)
 {
 	/* nop? */
@@ -306,12 +312,17 @@ skip_ws (CamelIMAPXStream *is, guchar *pp, guchar *pe)
 /* FIXME: these should probably handle it themselves,
    and get rid of the token interface? */
 gint
-camel_imapx_stream_atom (CamelIMAPXStream *is, guchar **data, guint *lenp, GError **error)
+camel_imapx_stream_atom (CamelIMAPXStream *is,
+                         guchar **data,
+                         guint *lenp,
+                         GCancellable *cancellable,
+                         GError **error)
 {
 	guchar *p, c;
+	GError *local_error = NULL;
 
 	/* this is only 'approximate' atom */
-	switch (camel_imapx_stream_token (is, data, lenp, NULL)) {
+	switch (camel_imapx_stream_token (is, data, lenp, cancellable, &local_error)) {
 	case IMAPX_TOK_TOKEN:
 		p = *data;
 		while ((c = *p))
@@ -319,9 +330,14 @@ camel_imapx_stream_atom (CamelIMAPXStream *is, guchar **data, guint *lenp, GErro
 	case IMAPX_TOK_INT:
 		return 0;
 	case IMAPX_TOK_ERROR:
+		if (local_error != NULL)
+			g_propagate_error (error, local_error);
 		return IMAPX_TOK_ERROR;
 	default:
-		g_set_error (error, CAMEL_IMAPX_ERROR, 1, "expecting atom");
+		if (local_error == NULL)
+			g_set_error (error, CAMEL_IMAPX_ERROR, 1, "expecting atom");
+		else
+			g_propagate_error (error, local_error);
 		io(is->tagprefix, "expecting atom!\n");
 		return IMAPX_TOK_PROTOCOL;
 	}
@@ -329,13 +345,17 @@ camel_imapx_stream_atom (CamelIMAPXStream *is, guchar **data, guint *lenp, GErro
 
 /* gets an atom, a quoted_string, or a literal */
 gint
-camel_imapx_stream_astring (CamelIMAPXStream *is, guchar **data, GError **error)
+camel_imapx_stream_astring (CamelIMAPXStream *is,
+                            guchar **data,
+                            GCancellable *cancellable,
+                            GError **error)
 {
 	guchar *p, *start;
 	guint len, inlen;
 	gint ret;
+	GError *local_error = NULL;
 
-	switch (camel_imapx_stream_token (is, data, &len, NULL)) {
+	switch (camel_imapx_stream_token (is, data, &len, cancellable, &local_error)) {
 	case IMAPX_TOK_TOKEN:
 	case IMAPX_TOK_INT:
 	case IMAPX_TOK_STRING:
@@ -346,7 +366,7 @@ camel_imapx_stream_astring (CamelIMAPXStream *is, guchar **data, GError **error)
 		p = is->tokenbuf;
 		camel_imapx_stream_set_literal (is, len);
 		do {
-			ret = camel_imapx_stream_getl (is, &start, &inlen);
+			ret = camel_imapx_stream_getl (is, &start, &inlen, cancellable, error);
 			if (ret < 0)
 				return ret;
 			memcpy (p, start, inlen);
@@ -357,9 +377,14 @@ camel_imapx_stream_astring (CamelIMAPXStream *is, guchar **data, GError **error)
 		return 0;
 	case IMAPX_TOK_ERROR:
 		/* wont get unless no exception hanlder*/
+		if (local_error != NULL)
+			g_propagate_error (error, local_error);
 		return IMAPX_TOK_ERROR;
 	default:
-		g_set_error (error, CAMEL_IMAPX_ERROR, 1, "expecting astring");
+		if (local_error == NULL)
+			g_set_error (error, CAMEL_IMAPX_ERROR, 1, "expecting astring");
+		else
+			g_propagate_error (error, local_error);
 		io(is->tagprefix, "expecting astring!\n");
 		return IMAPX_TOK_PROTOCOL;
 	}
@@ -367,13 +392,17 @@ camel_imapx_stream_astring (CamelIMAPXStream *is, guchar **data, GError **error)
 
 /* check for NIL or (small) quoted_string or literal */
 gint
-camel_imapx_stream_nstring (CamelIMAPXStream *is, guchar **data, GError **error)
+camel_imapx_stream_nstring (CamelIMAPXStream *is,
+                            guchar **data,
+                            GCancellable *cancellable,
+                            GError **error)
 {
 	guchar *p, *start;
 	guint len, inlen;
 	gint ret;
+	GError *local_error = NULL;
 
-	switch (camel_imapx_stream_token (is, data, &len, NULL)) {
+	switch (camel_imapx_stream_token (is, data, &len, cancellable, &local_error)) {
 	case IMAPX_TOK_STRING:
 		return 0;
 	case IMAPX_TOK_LITERAL:
@@ -382,7 +411,7 @@ camel_imapx_stream_nstring (CamelIMAPXStream *is, guchar **data, GError **error)
 		p = is->tokenbuf;
 		camel_imapx_stream_set_literal (is, len);
 		do {
-			ret = camel_imapx_stream_getl (is, &start, &inlen);
+			ret = camel_imapx_stream_getl (is, &start, &inlen, cancellable, error);
 			if (ret < 0)
 				return ret;
 			memcpy (p, start, inlen);
@@ -398,10 +427,15 @@ camel_imapx_stream_nstring (CamelIMAPXStream *is, guchar **data, GError **error)
 			return 0;
 		}
 	default:
-		g_set_error (error, CAMEL_IMAPX_ERROR, 1, "expecting nstring");
+		if (local_error == NULL)
+			g_set_error (error, CAMEL_IMAPX_ERROR, 1, "expecting nstring");
+		else
+			g_propagate_error (error, local_error);
 		return IMAPX_TOK_PROTOCOL;
 	case IMAPX_TOK_ERROR:
 		/* we'll never get this unless there are no exception  handlers anyway */
+		if (local_error != NULL)
+			g_propagate_error (error, local_error);
 		return IMAPX_TOK_ERROR;
 
 	}
@@ -409,17 +443,21 @@ camel_imapx_stream_nstring (CamelIMAPXStream *is, guchar **data, GError **error)
 
 /* parse an nstring as a stream */
 gint
-camel_imapx_stream_nstring_stream (CamelIMAPXStream *is, CamelStream **stream, GError **error)
+camel_imapx_stream_nstring_stream (CamelIMAPXStream *is,
+                                   CamelStream **stream,
+                                   GCancellable *cancellable,
+                                   GError **error)
 /* throws IO,PARSE exception */
 {
 	guchar *token;
 	guint len;
 	gint ret = 0;
 	CamelStream * mem = NULL;
+	GError *local_error = NULL;
 
 	*stream = NULL;
 
-	switch (camel_imapx_stream_token (is, &token, &len, NULL)) {
+	switch (camel_imapx_stream_token (is, &token, &len, cancellable, &local_error)) {
 		case IMAPX_TOK_STRING:
 			mem = camel_stream_mem_new_with_buffer ((gchar *)token, len);
 			*stream = mem;
@@ -428,7 +466,7 @@ camel_imapx_stream_nstring_stream (CamelIMAPXStream *is, CamelStream **stream, G
 			/* if len is big, we could automatically use a file backing */
 			camel_imapx_stream_set_literal (is, len);
 			mem = camel_stream_mem_new ();
-			if (camel_stream_write_to_stream ((CamelStream *)is, mem, error) == -1) {
+			if (camel_stream_write_to_stream ((CamelStream *)is, mem, cancellable, error) == -1) {
 				g_object_unref (mem);
 				ret = -1;
 				break;
@@ -443,20 +481,29 @@ camel_imapx_stream_nstring_stream (CamelIMAPXStream *is, CamelStream **stream, G
 			}
 		default:
 			ret = -1;
-			g_set_error (error, CAMEL_IMAPX_ERROR, 1, "nstring: token not string");
+			if (local_error == NULL)
+				g_set_error (error, CAMEL_IMAPX_ERROR, 1, "nstring: token not string");
+			else
+				g_propagate_error (error, local_error);
 	}
 
 	return ret;
 }
 
 guint64
-camel_imapx_stream_number (CamelIMAPXStream *is, GError **error)
+camel_imapx_stream_number (CamelIMAPXStream *is,
+                           GCancellable *cancellable,
+                           GError **error)
 {
 	guchar *token;
 	guint len;
+	GError *local_error = NULL;
 
-	if (camel_imapx_stream_token (is, &token, &len, NULL) != IMAPX_TOK_INT) {
-		g_set_error (error, CAMEL_IMAPX_ERROR, 1, "expecting number");
+	if (camel_imapx_stream_token (is, &token, &len, cancellable, &local_error) != IMAPX_TOK_INT) {
+		if (local_error == NULL)
+			g_set_error (error, CAMEL_IMAPX_ERROR, 1, "expecting number");
+		else
+			g_propagate_error (error, local_error);
 		return 0;
 	}
 
@@ -464,7 +511,10 @@ camel_imapx_stream_number (CamelIMAPXStream *is, GError **error)
 }
 
 gint
-camel_imapx_stream_text (CamelIMAPXStream *is, guchar **text, GError **error)
+camel_imapx_stream_text (CamelIMAPXStream *is,
+                         guchar **text,
+                         GCancellable *cancellable,
+                         GError **error)
 {
 	GByteArray *build = g_byte_array_new ();
 	guchar *token;
@@ -485,9 +535,8 @@ camel_imapx_stream_text (CamelIMAPXStream *is, guchar **text, GError **error)
 	}
 
 	do {
-		tok = camel_imapx_stream_gets (is, &token, &len);
+		tok = camel_imapx_stream_gets (is, &token, &len, cancellable, error);
 		if (tok < 0) {
-			g_set_error (error, CAMEL_IMAPX_ERROR, 1, "io error: %s", strerror(errno));
 			*text = NULL;
 			g_byte_array_free (build, TRUE);
 			return -1;
@@ -506,7 +555,11 @@ camel_imapx_stream_text (CamelIMAPXStream *is, guchar **text, GError **error)
 /* Get one token from the imap stream */
 camel_imapx_token_t
 /* throws IO,PARSE exception */
-camel_imapx_stream_token (CamelIMAPXStream *is, guchar **data, guint *len, GError **error)
+camel_imapx_stream_token (CamelIMAPXStream *is,
+                          guchar **data,
+                          guint *len,
+                          GCancellable *cancellable,
+                          GError **error)
 {
 	register guchar c, *oe;
 	guchar *o, *p, *e;
@@ -531,7 +584,7 @@ camel_imapx_stream_token (CamelIMAPXStream *is, guchar **data, guint *len, GErro
 	do {
 		while (p >= e ) {
 			is->ptr = p;
-			if (imapx_stream_fill (is, error) == IMAPX_TOK_ERROR)
+			if (imapx_stream_fill (is, cancellable, error) == IMAPX_TOK_ERROR)
 				return IMAPX_TOK_ERROR;
 			p = is->ptr;
 			e = is->end;
@@ -565,7 +618,7 @@ camel_imapx_stream_token (CamelIMAPXStream *is, guchar **data, guint *len, GErro
 							}
 						}
 						is->ptr = p;
-						if (imapx_stream_fill (is, error) == IMAPX_TOK_ERROR)
+						if (imapx_stream_fill (is, cancellable, error) == IMAPX_TOK_ERROR)
 							return IMAPX_TOK_ERROR;
 						p = is->ptr;
 						e = is->end;
@@ -580,7 +633,7 @@ camel_imapx_stream_token (CamelIMAPXStream *is, guchar **data, guint *len, GErro
 				}
 			}
 			is->ptr = p;
-			if (imapx_stream_fill (is, error) == IMAPX_TOK_ERROR)
+			if (imapx_stream_fill (is, cancellable, error) == IMAPX_TOK_ERROR)
 				return IMAPX_TOK_ERROR;
 			p = is->ptr;
 			e = is->end;
@@ -594,7 +647,7 @@ camel_imapx_stream_token (CamelIMAPXStream *is, guchar **data, guint *len, GErro
 				if (c == '\\') {
 					while (p >= e) {
 						is->ptr = p;
-						if (imapx_stream_fill (is, error) == IMAPX_TOK_ERROR)
+						if (imapx_stream_fill (is, cancellable, error) == IMAPX_TOK_ERROR)
 							return IMAPX_TOK_ERROR;
 						p = is->ptr;
 						e = is->end;
@@ -620,7 +673,7 @@ camel_imapx_stream_token (CamelIMAPXStream *is, guchar **data, guint *len, GErro
 				*o++ = c;
 			}
 			is->ptr = p;
-			if (imapx_stream_fill (is, error) == IMAPX_TOK_ERROR)
+			if (imapx_stream_fill (is, cancellable, error) == IMAPX_TOK_ERROR)
 				return IMAPX_TOK_ERROR;
 			p = is->ptr;
 			e = is->end;
@@ -655,7 +708,7 @@ camel_imapx_stream_token (CamelIMAPXStream *is, guchar **data, guint *len, GErro
 				*o++ = c;
 			}
 			is->ptr = p;
-			if (imapx_stream_fill (is, error) == IMAPX_TOK_ERROR)
+			if (imapx_stream_fill (is, cancellable, error) == IMAPX_TOK_ERROR)
 				return IMAPX_TOK_ERROR;
 			p = is->ptr;
 			e = is->end;
@@ -686,7 +739,12 @@ camel_imapx_stream_ungettoken (CamelIMAPXStream *is, camel_imapx_token_t tok, gu
 }
 
 /* returns -1 on error, 0 if last lot of data, >0 if more remaining */
-gint camel_imapx_stream_gets (CamelIMAPXStream *is, guchar **start, guint *len)
+gint
+camel_imapx_stream_gets (CamelIMAPXStream *is,
+                         guchar **start,
+                         guint *len,
+                         GCancellable *cancellable,
+                         GError **error)
 {
 	gint max;
 	guchar *end;
@@ -695,7 +753,7 @@ gint camel_imapx_stream_gets (CamelIMAPXStream *is, guchar **start, guint *len)
 
 	max = is->end - is->ptr;
 	if (max == 0) {
-		max = imapx_stream_fill (is, NULL);
+		max = imapx_stream_fill (is, cancellable, error);
 		if (max <= 0)
 			return max;
 	}
@@ -717,7 +775,12 @@ void camel_imapx_stream_set_literal (CamelIMAPXStream *is, guint literal)
 }
 
 /* returns -1 on erorr, 0 if last data, >0 if more data left */
-gint camel_imapx_stream_getl (CamelIMAPXStream *is, guchar **start, guint *len)
+gint
+camel_imapx_stream_getl (CamelIMAPXStream *is,
+                         guchar **start,
+                         guint *len,
+                         GCancellable *cancellable,
+                         GError **error)
 {
 	gint max;
 
@@ -726,7 +789,7 @@ gint camel_imapx_stream_getl (CamelIMAPXStream *is, guchar **start, guint *len)
 	if (is->literal > 0) {
 		max = is->end - is->ptr;
 		if (max == 0) {
-			max = imapx_stream_fill (is, NULL);
+			max = imapx_stream_fill (is, cancellable, error);
 			if (max <= 0)
 				return max;
 		}
@@ -746,17 +809,19 @@ gint camel_imapx_stream_getl (CamelIMAPXStream *is, guchar **start, guint *len)
 
 /* skip the rest of the line of tokens */
 gint
-camel_imapx_stream_skip (CamelIMAPXStream *is, GError **error)
+camel_imapx_stream_skip (CamelIMAPXStream *is,
+                         GCancellable *cancellable,
+                         GError **error)
 {
 	gint tok;
 	guchar *token;
 	guint len;
 
 	do {
-		tok = camel_imapx_stream_token (is, &token, &len, error);
+		tok = camel_imapx_stream_token (is, &token, &len, cancellable, error);
 		if (tok == IMAPX_TOK_LITERAL) {
 			camel_imapx_stream_set_literal (is, len);
-			while ((tok = camel_imapx_stream_getl (is, &token, &len)) > 0) {
+			while ((tok = camel_imapx_stream_getl (is, &token, &len, cancellable, error)) > 0) {
 				io(is->tagprefix, "Skip literal data '%.*s'\n", (gint)len, token);
 			}
 		}
diff --git a/camel/providers/imapx/camel-imapx-stream.h b/camel/providers/imapx/camel-imapx-stream.h
index 4ed5e58..a6de847 100644
--- a/camel/providers/imapx/camel-imapx-stream.h
+++ b/camel/providers/imapx/camel-imapx-stream.h
@@ -94,6 +94,7 @@ camel_imapx_token_t
 		camel_imapx_stream_token	(CamelIMAPXStream *is,
 						 guchar **start,
 						 guint *len,
+						 GCancellable *cancellable,
 						 GError **error);
 
 void		camel_imapx_stream_ungettoken	(CamelIMAPXStream *is,
@@ -104,10 +105,14 @@ void		camel_imapx_stream_set_literal	(CamelIMAPXStream *is,
 						 guint literal);
 gint		camel_imapx_stream_gets		(CamelIMAPXStream *is,
 						 guchar **start,
-						 guint *len);
+						 guint *len,
+						 GCancellable *cancellable,
+						 GError **error);
 gint		 camel_imapx_stream_getl	(CamelIMAPXStream *is,
 						 guchar **start,
-						 guint *len);
+						 guint *len,
+						 GCancellable *cancellable,
+						 GError **error);
 
 /* all throw IO,PARSE exceptions */
 
@@ -115,31 +120,38 @@ gint		 camel_imapx_stream_getl	(CamelIMAPXStream *is,
 gint		camel_imapx_stream_atom		(CamelIMAPXStream *is,
 						 guchar **start,
 						 guint *len,
+						 GCancellable *cancellable,
 						 GError **error);
 /* gets an atom or string */
 gint		camel_imapx_stream_astring	(CamelIMAPXStream *is,
 						 guchar **start,
+						 GCancellable *cancellable,
 						 GError **error);
 /* gets a NIL or a string, start==NULL if NIL */
 gint		camel_imapx_stream_nstring	(CamelIMAPXStream *is,
 						 guchar **start,
+						 GCancellable *cancellable,
 						 GError **error);
 /* gets a NIL or string into a stream, stream==NULL if NIL */
 gint		camel_imapx_stream_nstring_stream
 						(CamelIMAPXStream *is,
 						 CamelStream **stream,
+						 GCancellable *cancellable,
 						 GError **error);
 /* gets 'text' */
 gint		camel_imapx_stream_text		(CamelIMAPXStream *is,
 						 guchar **text,
+						 GCancellable *cancellable,
 						 GError **error);
 
 /* gets a 'number' */
 guint64		 camel_imapx_stream_number	(CamelIMAPXStream *is,
+						 GCancellable *cancellable,
 						 GError **error);
 
 /* skips the rest of a line, including literals, etc */
 gint		camel_imapx_stream_skip		(CamelIMAPXStream *is,
+						 GCancellable *cancellable,
 						 GError **error);
 
 G_END_DECLS
diff --git a/camel/providers/imapx/camel-imapx-utils.c b/camel/providers/imapx/camel-imapx-utils.c
index 5e5caf3..d3d569a 100644
--- a/camel/providers/imapx/camel-imapx-utils.c
+++ b/camel/providers/imapx/camel-imapx-utils.c
@@ -97,7 +97,11 @@ static struct {
    shoudl this be part of imapx-driver? */
 /* mabye this should be a stream op? */
 void
-imapx_parse_flags (CamelIMAPXStream *stream, guint32 *flagsp, CamelFlag **user_flagsp, GError **error)
+imapx_parse_flags (CamelIMAPXStream *stream,
+                   guint32 *flagsp,
+                   CamelFlag **user_flagsp,
+                   GCancellable *cancellable,
+                   GError **error)
 /* throws IO,PARSE exception */
 {
 	gint tok, i;
@@ -107,10 +111,10 @@ imapx_parse_flags (CamelIMAPXStream *stream, guint32 *flagsp, CamelFlag **user_f
 
 	*flagsp = flags;
 
-	tok = camel_imapx_stream_token (stream, &token, &len, NULL);
+	tok = camel_imapx_stream_token (stream, &token, &len, cancellable, NULL);
 	if (tok == '(') {
 		do {
-			tok = camel_imapx_stream_token (stream, &token, &len, NULL);
+			tok = camel_imapx_stream_token (stream, &token, &len, cancellable, NULL);
 			if (tok == IMAPX_TOK_TOKEN || tok == IMAPX_TOK_INT) {
 				gchar *upper = g_ascii_strup ((gchar *) token, len);
 
@@ -177,13 +181,17 @@ rename_label_flag (const gchar *flag, gint len, gboolean server_to_evo)
 }
 
 void
-imapx_write_flags (CamelStream *stream, guint32 flags, CamelFlag *user_flags, GError **error)
+imapx_write_flags (CamelStream *stream,
+                   guint32 flags,
+                   CamelFlag *user_flags,
+                   GCancellable *cancellable,
+                   GError **error)
 /* throws IO exception */
 {
 	gint i;
 	gboolean first = TRUE;
 
-	if (camel_stream_write(stream, "(", 1, error) == -1) {
+	if (camel_stream_write(stream, "(", 1, cancellable, error) == -1) {
 		return;
 	}
 
@@ -191,11 +199,11 @@ imapx_write_flags (CamelStream *stream, guint32 flags, CamelFlag *user_flags, GE
 		if (flag_table[i].flag & flags) {
 			if (flags & CAMEL_IMAPX_MESSAGE_RECENT)
 				continue;
-			if (!first && camel_stream_write(stream, " ", 1, error) == -1) {
+			if (!first && camel_stream_write(stream, " ", 1, cancellable, error) == -1) {
 				return;
 			}
 			first = FALSE;
-			if (camel_stream_write (stream, flag_table[i].name, strlen (flag_table[i].name), error) == -1) {
+			if (camel_stream_write (stream, flag_table[i].name, strlen (flag_table[i].name), cancellable, error) == -1) {
 				return;
 			}
 
@@ -206,18 +214,18 @@ imapx_write_flags (CamelStream *stream, guint32 flags, CamelFlag *user_flags, GE
 	while (user_flags) {
 		const gchar *flag_name = rename_label_flag (user_flags->name, strlen (user_flags->name), FALSE);
 
-		if (!first && camel_stream_write(stream, " ", 1, error) == -1) {
+		if (!first && camel_stream_write(stream, " ", 1, cancellable, error) == -1) {
 			return;
 		}
 		first = FALSE;
-		if (camel_stream_write (stream, flag_name, strlen (flag_name), error) == -1) {
+		if (camel_stream_write (stream, flag_name, strlen (flag_name), cancellable, error) == -1) {
 			return;
 		}
 
 		user_flags = user_flags->next;
 	}
 
-	if (camel_stream_write(stream, ")", 1, error) == -1) {
+	if (camel_stream_write(stream, ")", 1, cancellable, error) == -1) {
 		return;
 	}
 }
@@ -443,7 +451,9 @@ struct {
 };
 
 struct _capability_info *
-imapx_parse_capability (CamelIMAPXStream *stream, GError **error)
+imapx_parse_capability (CamelIMAPXStream *stream,
+                        GCancellable *cancellable,
+                        GError **error)
 {
 	gint tok, i;
 	guint len;
@@ -456,7 +466,7 @@ imapx_parse_capability (CamelIMAPXStream *stream, GError **error)
 	cinfo->auth_types = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL);
 
 	/* FIXME: handle auth types */
-	while ((tok = camel_imapx_stream_token (stream, &token, &len, &local_error)) != '\n' &&
+	while ((tok = camel_imapx_stream_token (stream, &token, &len, cancellable, &local_error)) != '\n' &&
 		local_error == NULL) {
 		switch (tok) {
 			case ']':
@@ -510,7 +520,9 @@ void imapx_free_capability (struct _capability_info *cinfo)
 }
 
 struct _CamelIMAPXNamespaceList *
-imapx_parse_namespace_list (CamelIMAPXStream *stream, GError **error)
+imapx_parse_namespace_list (CamelIMAPXStream *stream,
+                            GCancellable *cancellable,
+                            GError **error)
 {
 	CamelIMAPXStoreNamespace *namespaces[3], *node, *tail;
 	CamelIMAPXNamespaceList *nsl = NULL;
@@ -524,16 +536,16 @@ imapx_parse_namespace_list (CamelIMAPXStream *stream, GError **error)
 	nsl->shared = NULL;
 	nsl->other = NULL;
 
-	tok = camel_imapx_stream_token (stream, &token, &len, NULL);
+	tok = camel_imapx_stream_token (stream, &token, &len, cancellable, NULL);
 	do {
 		namespaces[n] = NULL;
 		tail = (CamelIMAPXStoreNamespace *) &namespaces[n];
 
 		if (tok == '(') {
-			tok = camel_imapx_stream_token (stream, &token, &len, NULL);
+			tok = camel_imapx_stream_token (stream, &token, &len, cancellable, NULL);
 
 			while (tok == '(') {
-				tok = camel_imapx_stream_token (stream, &token, &len, NULL);
+				tok = camel_imapx_stream_token (stream, &token, &len, cancellable, NULL);
 				if (tok != IMAPX_TOK_STRING) {
 					g_set_error (error, 1, CAMEL_IMAPX_ERROR, "namespace: expected a string path name");
 					goto exception;
@@ -543,7 +555,7 @@ imapx_parse_namespace_list (CamelIMAPXStream *stream, GError **error)
 				node->next = NULL;
 				node->path = g_strdup ((gchar *) token);
 
-				tok = camel_imapx_stream_token (stream, &token, &len, NULL);
+				tok = camel_imapx_stream_token (stream, &token, &len, cancellable, NULL);
 
 				if (tok == IMAPX_TOK_STRING) {
 					if (strlen ((gchar *) token) == 1) {
@@ -577,13 +589,13 @@ imapx_parse_namespace_list (CamelIMAPXStream *stream, GError **error)
 				/* TODO remove full_name later. not required */
 				node->full_name = g_strdup (node->path);
 
-				tok = camel_imapx_stream_token (stream, &token, &len, NULL);
+				tok = camel_imapx_stream_token (stream, &token, &len, cancellable, NULL);
 				if (tok != ')') {
 					g_set_error (error, CAMEL_IMAPX_ERROR, 1, "namespace: expected a ')'");
 					goto exception;
 				}
 
-				tok = camel_imapx_stream_token (stream, &token, &len, NULL);
+				tok = camel_imapx_stream_token (stream, &token, &len, cancellable, NULL);
 			}
 
 			if (tok != ')') {
@@ -598,7 +610,7 @@ imapx_parse_namespace_list (CamelIMAPXStream *stream, GError **error)
 			goto exception;
 		}
 
-		tok = camel_imapx_stream_token (stream, &token, &len, NULL);
+		tok = camel_imapx_stream_token (stream, &token, &len, cancellable, NULL);
 		n++;
 	} while (n < 3);
 
@@ -754,7 +766,10 @@ imapx_free_body (struct _CamelMessageContentInfo *cinfo)
 }
 
 gboolean
-imapx_parse_param_list (CamelIMAPXStream *is, struct _camel_header_param **plist, GError **error)
+imapx_parse_param_list (CamelIMAPXStream *is,
+                        struct _camel_header_param **plist,
+                        GCancellable *cancellable,
+                        GError **error)
 {
 	gint tok;
 	guint len;
@@ -764,18 +779,18 @@ imapx_parse_param_list (CamelIMAPXStream *is, struct _camel_header_param **plist
 	p(is->tagprefix, "body_fld_param\n");
 
 	/* body_fld_param  ::= "(" 1#(string SPACE string) ")" / nil */
-	tok = camel_imapx_stream_token (is, &token, &len, NULL);
+	tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL);
 	if (tok == '(') {
 		while (1) {
-			tok = camel_imapx_stream_token (is, &token, &len, NULL);
+			tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL);
 			if (tok == ')')
 				break;
 			camel_imapx_stream_ungettoken (is, tok, token, len);
 
-			camel_imapx_stream_astring (is, &token, NULL);
+			camel_imapx_stream_astring (is, &token, cancellable, NULL);
 			param = alloca (strlen ((gchar *) token)+1);
 			strcpy (param, (gchar *) token);
-			camel_imapx_stream_astring (is, &token, NULL);
+			camel_imapx_stream_astring (is, &token, cancellable, NULL);
 			camel_header_set_param (plist, param, (gchar *) token);
 		}
 	} /* else check nil?  no need */
@@ -784,7 +799,9 @@ imapx_parse_param_list (CamelIMAPXStream *is, struct _camel_header_param **plist
 }
 
 struct _CamelContentDisposition *
-imapx_parse_ext_optional (CamelIMAPXStream *is, GError **error)
+imapx_parse_ext_optional (CamelIMAPXStream *is,
+                          GCancellable *cancellable,
+                          GError **error)
 {
 	gint tok;
 	guint len;
@@ -809,16 +826,16 @@ imapx_parse_ext_optional (CamelIMAPXStream *is, GError **error)
 
 	/* body_fld_dsp    ::= "(" string SPACE body_fld_param ")" / nil */
 
-	tok = camel_imapx_stream_token (is, &token, &len, NULL);
+	tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL);
 	switch (tok) {
 		case '(':
 			dinfo = g_malloc0 (sizeof (*dinfo));
 			dinfo->refcount = 1;
 			/* should be string */
-			camel_imapx_stream_astring (is, &token, NULL);
+			camel_imapx_stream_astring (is, &token, cancellable, NULL);
 
 			dinfo->disposition = g_strdup ((gchar *) token);
-			imapx_parse_param_list (is, &dinfo->params, NULL);
+			imapx_parse_param_list (is, &dinfo->params, cancellable, NULL);
 		case IMAPX_TOK_TOKEN:
 			d(is->tagprefix, "body_fld_dsp: NIL\n");
 			break;
@@ -833,11 +850,11 @@ imapx_parse_ext_optional (CamelIMAPXStream *is, GError **error)
 
 	/* we just drop the lang string/list, save it somewhere? */
 
-	tok = camel_imapx_stream_token (is, &token, &len, &local_error);
+	tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error);
 	switch (tok) {
 		case '(':
 			while (1) {
-				tok = camel_imapx_stream_token (is, &token, &len, &local_error);
+				tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error);
 				if (tok == ')') {
 					break;
 				} else if (tok != IMAPX_TOK_STRING) {
@@ -857,7 +874,7 @@ imapx_parse_ext_optional (CamelIMAPXStream *is, GError **error)
 		case IMAPX_TOK_LITERAL:
 			/* we have a literal string */
 			camel_imapx_stream_set_literal (is, len);
-			while ((tok = camel_imapx_stream_getl (is, &token, &len)) > 0) {
+			while ((tok = camel_imapx_stream_getl (is, &token, &len, cancellable, NULL)) > 0) {
 				d(is->tagprefix, "Skip literal data '%.*s'\n", (gint)len, token);
 			}
 			break;
@@ -875,7 +892,9 @@ imapx_parse_ext_optional (CamelIMAPXStream *is, GError **error)
 }
 
 struct _CamelMessageContentInfo *
-imapx_parse_body_fields (CamelIMAPXStream *is, GError **error)
+imapx_parse_body_fields (CamelIMAPXStream *is,
+                         GCancellable *cancellable,
+                         GError **error)
 {
 	guchar *token;
 	gchar  *type;
@@ -891,34 +910,34 @@ imapx_parse_body_fields (CamelIMAPXStream *is, GError **error)
 	cinfo = g_malloc0 (sizeof (*cinfo));
 
 	/* this should be string not astring */
-	if (camel_imapx_stream_astring (is, &token, error))
+	if (camel_imapx_stream_astring (is, &token, cancellable, error))
 		goto error;
 	type = alloca (strlen ( (gchar *) token)+1);
 	strcpy (type, (gchar *) token);
-	if (camel_imapx_stream_astring (is, &token, error))
+	if (camel_imapx_stream_astring (is, &token, cancellable, error))
 		goto error;
 	cinfo->type = camel_content_type_new (type, (gchar *) token);
-	if (!imapx_parse_param_list (is, &cinfo->type->params, error))
+	if (!imapx_parse_param_list (is, &cinfo->type->params, cancellable, error))
 		goto error;
 
 	/* body_fld_id     ::= nstring */
-	if (!camel_imapx_stream_nstring (is, &token, error))
+	if (!camel_imapx_stream_nstring (is, &token, cancellable, error))
 		goto error;
 	cinfo->id = g_strdup ((gchar *) token);
 
 	/* body_fld_desc   ::= nstring */
-	if (!camel_imapx_stream_nstring (is, &token, error))
+	if (!camel_imapx_stream_nstring (is, &token, cancellable, error))
 		goto error;
 	cinfo->description = g_strdup ((gchar *) token);
 
 	/* body_fld_enc    ::= (<"> ("7BIT" / "8BIT" / "BINARY" / "BASE64"/
 	   "QUOTED-PRINTABLE") <">) / string */
-	if (camel_imapx_stream_astring (is, &token, error))
+	if (camel_imapx_stream_astring (is, &token, cancellable, error))
 		goto error;
 	cinfo->encoding = g_strdup ((gchar *) token);
 
 	/* body_fld_octets ::= number */
-	cinfo->size = camel_imapx_stream_number (is, &local_error);
+	cinfo->size = camel_imapx_stream_number (is, cancellable, &local_error);
 	if (local_error != NULL) {
 		g_propagate_error (error, local_error);
 		goto error;
@@ -931,7 +950,9 @@ error:
 }
 
 struct _camel_header_address *
-imapx_parse_address_list (CamelIMAPXStream *is, GError **error)
+imapx_parse_address_list (CamelIMAPXStream *is,
+                          GCancellable *cancellable,
+                          GError **error)
 /* throws PARSE,IO exception */
 {
 	gint tok;
@@ -943,14 +964,14 @@ imapx_parse_address_list (CamelIMAPXStream *is, GError **error)
 
 	/* "(" 1*address ")" / nil */
 
-	tok = camel_imapx_stream_token (is, &token, &len, &local_error);
+	tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error);
 	if (tok == '(') {
 		while (1) {
 			struct _camel_header_address *addr, *group = NULL;
 
 			/* address         ::= "(" addr_name SPACE addr_adl SPACE addr_mailbox
 			   SPACE addr_host ")" */
-			tok = camel_imapx_stream_token (is, &token, &len, &local_error);
+			tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error);
 			if (tok == ')')
 				break;
 			if (tok != '(') {
@@ -962,10 +983,10 @@ imapx_parse_address_list (CamelIMAPXStream *is, GError **error)
 
 			addr = camel_header_address_new ();
 			addr->type = CAMEL_HEADER_ADDRESS_NAME;
-			tok = camel_imapx_stream_nstring (is, &token, &local_error);
+			tok = camel_imapx_stream_nstring (is, &token, cancellable, &local_error);
 			addr->name = g_strdup ((gchar *) token);
 			/* we ignore the route, nobody uses it in the real world */
-			tok = camel_imapx_stream_nstring (is, &token, &local_error);
+			tok = camel_imapx_stream_nstring (is, &token, cancellable, &local_error);
 
 			/* [RFC-822] group syntax is indicated by a special
 			   form of address structure in which the host name
@@ -975,9 +996,9 @@ imapx_parse_address_list (CamelIMAPXStream *is, GError **error)
 			   non-NIL, this is a start of group marker, and the
 			   mailbox name field holds the group name phrase. */
 
-			tok = camel_imapx_stream_nstring (is,(guchar **) &mbox, &local_error);
+			tok = camel_imapx_stream_nstring (is,(guchar **) &mbox, cancellable, &local_error);
 			mbox = g_strdup (mbox);
-			tok = camel_imapx_stream_nstring (is, &host, &local_error);
+			tok = camel_imapx_stream_nstring (is, &host, cancellable, &local_error);
 			if (host == NULL) {
 				if (mbox == NULL) {
 					group = NULL;
@@ -999,7 +1020,7 @@ imapx_parse_address_list (CamelIMAPXStream *is, GError **error)
 					camel_header_address_list_append (&list, addr);
 			}
 			do {
-				tok = camel_imapx_stream_token (is, &token, &len, &local_error);
+				tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error);
 			} while (tok != ')');
 		}
 	} else {
@@ -1014,7 +1035,9 @@ imapx_parse_address_list (CamelIMAPXStream *is, GError **error)
 }
 
 struct _CamelMessageInfo *
-imapx_parse_envelope (CamelIMAPXStream *is, GError **error)
+imapx_parse_envelope (CamelIMAPXStream *is,
+                      GCancellable *cancellable,
+                      GError **error)
 {
 	gint tok;
 	guint len;
@@ -1033,7 +1056,7 @@ imapx_parse_envelope (CamelIMAPXStream *is, GError **error)
 
 	minfo = (CamelMessageInfoBase *)camel_message_info_new (NULL);
 
-	tok = camel_imapx_stream_token (is, &token, &len, &local_error);
+	tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error);
 	if (tok != '(') {
 		g_clear_error (&local_error);
 		camel_message_info_free (minfo);
@@ -1042,20 +1065,20 @@ imapx_parse_envelope (CamelIMAPXStream *is, GError **error)
 	}
 
 	/* env_date        ::= nstring */
-	camel_imapx_stream_nstring (is, &token, &local_error);
+	camel_imapx_stream_nstring (is, &token, cancellable, &local_error);
 	minfo->date_sent = camel_header_decode_date ((gchar *) token, NULL);
 
 	/* env_subject     ::= nstring */
-	tok = camel_imapx_stream_nstring (is, &token, &local_error);
+	tok = camel_imapx_stream_nstring (is, &token, cancellable, &local_error);
 	minfo->subject = camel_pstring_strdup ((gchar *) token);
 
 	/* we merge from/sender into from, append should probably merge more smartly? */
 
 	/* env_from        ::= "(" 1*address ")" / nil */
-	addr_from = imapx_parse_address_list (is, &local_error);
+	addr_from = imapx_parse_address_list (is, cancellable, &local_error);
 
 	/* env_sender      ::= "(" 1*address ")" / nil */
-	addr = imapx_parse_address_list (is, &local_error);
+	addr = imapx_parse_address_list (is, cancellable, &local_error);
 	if (addr_from) {
 		camel_header_address_list_clear (&addr);
 #if 0
@@ -1077,11 +1100,11 @@ imapx_parse_envelope (CamelIMAPXStream *is, GError **error)
 	/* we dont keep reply_to */
 
 	/* env_reply_to    ::= "(" 1*address ")" / nil */
-	addr = imapx_parse_address_list (is, &local_error);
+	addr = imapx_parse_address_list (is, cancellable, &local_error);
 	camel_header_address_list_clear (&addr);
 
 	/* env_to          ::= "(" 1*address ")" / nil */
-	addr = imapx_parse_address_list (is, &local_error);
+	addr = imapx_parse_address_list (is, cancellable, &local_error);
 	if (addr) {
 		addrstr = camel_header_address_list_format (addr);
 		minfo->to = camel_pstring_strdup (addrstr);
@@ -1090,7 +1113,7 @@ imapx_parse_envelope (CamelIMAPXStream *is, GError **error)
 	}
 
 	/* env_cc          ::= "(" 1*address ")" / nil */
-	addr = imapx_parse_address_list (is, &local_error);
+	addr = imapx_parse_address_list (is, cancellable, &local_error);
 	if (addr) {
 		addrstr = camel_header_address_list_format (addr);
 		minfo->cc = camel_pstring_strdup (addrstr);
@@ -1101,20 +1124,20 @@ imapx_parse_envelope (CamelIMAPXStream *is, GError **error)
 	/* we dont keep bcc either */
 
 	/* env_bcc         ::= "(" 1*address ")" / nil */
-	addr = imapx_parse_address_list (is, &local_error);
+	addr = imapx_parse_address_list (is, cancellable, &local_error);
 	camel_header_address_list_clear (&addr);
 
 	/* FIXME: need to put in-reply-to into references hash list */
 
 	/* env_in_reply_to ::= nstring */
-	tok = camel_imapx_stream_nstring (is, &token, &local_error);
+	tok = camel_imapx_stream_nstring (is, &token, cancellable, &local_error);
 
 	/* FIXME: need to put message-id into message-id hash */
 
 	/* env_message_id  ::= nstring */
-	tok = camel_imapx_stream_nstring (is, &token, &local_error);
+	tok = camel_imapx_stream_nstring (is, &token, cancellable, &local_error);
 
-	tok = camel_imapx_stream_token (is, &token, &len, &local_error);
+	tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error);
 	if (tok != ')') {
 		g_clear_error (&local_error);
 		camel_message_info_free (minfo);
@@ -1130,7 +1153,9 @@ imapx_parse_envelope (CamelIMAPXStream *is, GError **error)
 }
 
 struct _CamelMessageContentInfo *
-imapx_parse_body (CamelIMAPXStream *is, GError **error)
+imapx_parse_body (CamelIMAPXStream *is,
+                  GCancellable *cancellable,
+                  GError **error)
 {
 	gint tok;
 	guint len;
@@ -1145,14 +1170,14 @@ imapx_parse_body (CamelIMAPXStream *is, GError **error)
 
 	p(is->tagprefix, "body\n");
 
-	tok = camel_imapx_stream_token (is, &token, &len, &local_error);
+	tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error);
 	if (tok != '(') {
 		g_set_error (error, CAMEL_IMAPX_ERROR, 1, "body: expecting '('");
 		return NULL;
 	}
 
 	/* 1*body (optional for multiparts) */
-	tok = camel_imapx_stream_token (is, &token, &len, &local_error);
+	tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error);
 	camel_imapx_stream_ungettoken (is, tok, token, len);
 	if (tok == '(') {
 		/* body_type_mpart ::= 1*body SPACE media_subtype
@@ -1161,17 +1186,17 @@ imapx_parse_body (CamelIMAPXStream *is, GError **error)
 		cinfo = g_malloc0 (sizeof (*cinfo));
 		last = (struct _CamelMessageContentInfo *)&cinfo->childs;
 		do {
-			subinfo = imapx_parse_body (is, &local_error);
+			subinfo = imapx_parse_body (is, cancellable, &local_error);
 			last->next = subinfo;
 			last = subinfo;
 			subinfo->parent = cinfo;
-			tok = camel_imapx_stream_token (is, &token, &len, &local_error);
+			tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error);
 			camel_imapx_stream_ungettoken (is, tok, token, len);
 		} while (tok == '(');
 
 		d(is->tagprefix, "media_subtype\n");
 
-		camel_imapx_stream_astring (is, &token, &local_error);
+		camel_imapx_stream_astring (is, &token, cancellable, &local_error);
 		cinfo->type = camel_content_type_new("multipart", (gchar *) token);
 
 		/* body_ext_mpart  ::= body_fld_param
@@ -1182,17 +1207,17 @@ imapx_parse_body (CamelIMAPXStream *is, GError **error)
 
 		d(is->tagprefix, "body_ext_mpart\n");
 
-		tok = camel_imapx_stream_token (is, &token, &len, &local_error);
+		tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error);
 		camel_imapx_stream_ungettoken (is, tok, token, len);
 		if (tok == '(') {
-			imapx_parse_param_list (is, &cinfo->type->params, &local_error);
+			imapx_parse_param_list (is, &cinfo->type->params, cancellable, &local_error);
 
 			/* body_fld_dsp    ::= "(" string SPACE body_fld_param ")" / nil */
 
-			tok = camel_imapx_stream_token (is, &token, &len, &local_error);
+			tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error);
 			camel_imapx_stream_ungettoken (is, tok, token, len);
 			if (tok == '(' || tok == IMAPX_TOK_TOKEN) {
-				dinfo = imapx_parse_ext_optional (is, &local_error);
+				dinfo = imapx_parse_ext_optional (is, cancellable, &local_error);
 				/* other extension fields?, soaked up below */
 			} else {
 				camel_imapx_stream_ungettoken (is, tok, token, len);
@@ -1209,16 +1234,16 @@ imapx_parse_body (CamelIMAPXStream *is, GError **error)
 
 		d(is->tagprefix, "Single part body\n");
 
-		cinfo = imapx_parse_body_fields (is, &local_error);
+		cinfo = imapx_parse_body_fields (is, cancellable, &local_error);
 
 		d(is->tagprefix, "envelope?\n");
 
 		/* do we have an envelope following */
-		tok = camel_imapx_stream_token (is, &token, &len, &local_error);
+		tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error);
 		camel_imapx_stream_ungettoken (is, tok, token, len);
 		if (tok == '(') {
 			/* what do we do with the envelope?? */
-			minfo = imapx_parse_envelope (is, &local_error);
+			minfo = imapx_parse_envelope (is, cancellable, &local_error);
 			/* what do we do with the message content info?? */
 			//((CamelMessageInfoBase *)minfo)->content = imapx_parse_body (is);
 			camel_message_info_free (minfo);
@@ -1229,10 +1254,10 @@ imapx_parse_body (CamelIMAPXStream *is, GError **error)
 		d(is->tagprefix, "fld_lines?\n");
 
 		/* do we have fld_lines following? */
-		tok = camel_imapx_stream_token (is, &token, &len, &local_error);
+		tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error);
 		if (tok == IMAPX_TOK_INT) {
 			d(is->tagprefix, "field lines: %s\n", token);
-			tok = camel_imapx_stream_token (is, &token, &len, &local_error);
+			tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error);
 		}
 		camel_imapx_stream_ungettoken (is, tok, token, len);
 
@@ -1245,16 +1270,16 @@ imapx_parse_body (CamelIMAPXStream *is, GError **error)
 		d(is->tagprefix, "extension data?\n");
 
 		if (tok != ')') {
-			camel_imapx_stream_nstring (is, &token, &local_error);
+			camel_imapx_stream_nstring (is, &token, cancellable, &local_error);
 
 			d(is->tagprefix, "md5: %s\n", token?(gchar *)token:"NIL");
 
 			/* body_fld_dsp    ::= "(" string SPACE body_fld_param ")" / nil */
 
-			tok = camel_imapx_stream_token (is, &token, &len, &local_error);
+			tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error);
 			camel_imapx_stream_ungettoken (is, tok, token, len);
 			if (tok == '(' || tok == IMAPX_TOK_TOKEN) {
-				dinfo = imapx_parse_ext_optional (is, &local_error);
+				dinfo = imapx_parse_ext_optional (is, cancellable, &local_error);
 				/* then other extension fields, soaked up below */
 			}
 		}
@@ -1263,7 +1288,7 @@ imapx_parse_body (CamelIMAPXStream *is, GError **error)
 	/* soak up any other extension fields that may be present */
 	/* there should only be simple tokens, no lists */
 	do {
-		tok = camel_imapx_stream_token (is, &token, &len, &local_error);
+		tok = camel_imapx_stream_token (is, &token, &len, cancellable, &local_error);
 		if (tok != ')') {
 			d(is->tagprefix, "Dropping extension data '%s'\n", token);
 		}
@@ -1289,7 +1314,9 @@ imapx_parse_body (CamelIMAPXStream *is, GError **error)
 }
 
 gchar *
-imapx_parse_section (CamelIMAPXStream *is, GError **error)
+imapx_parse_section (CamelIMAPXStream *is,
+                     GCancellable *cancellable,
+                     GError **error)
 {
 	gint tok;
 	guint len;
@@ -1307,13 +1334,13 @@ imapx_parse_section (CamelIMAPXStream *is, GError **error)
 	  SPACE header_list / "TEXT"
 	*/
 
-	tok = camel_imapx_stream_token (is, &token, &len, NULL);
+	tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL);
 	if (tok != '[') {
 		g_set_error (error, CAMEL_IMAPX_ERROR, 1, "section: expecting '['");
 		return NULL;
 	}
 
-	tok = camel_imapx_stream_token (is, &token, &len, NULL);
+	tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL);
 	if (tok == IMAPX_TOK_INT || tok == IMAPX_TOK_TOKEN)
 		section = g_strdup ((gchar *) token);
 	else if (tok == ']') {
@@ -1328,10 +1355,10 @@ imapx_parse_section (CamelIMAPXStream *is, GError **error)
 	   header_fld_name ::= astring */
 
 	/* we dont need the header specifiers */
-	tok = camel_imapx_stream_token (is, &token, &len, NULL);
+	tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL);
 	if (tok == '(') {
 		do {
-			tok = camel_imapx_stream_token (is, &token, &len, NULL);
+			tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL);
 			if (tok == IMAPX_TOK_STRING || tok == IMAPX_TOK_TOKEN || tok == IMAPX_TOK_INT) {
 				/* ?do something? */
 			} else if (tok != ')') {
@@ -1340,7 +1367,7 @@ imapx_parse_section (CamelIMAPXStream *is, GError **error)
 				return NULL;
 			}
 		} while (tok != ')');
-		tok = camel_imapx_stream_token (is, &token, &len, NULL);
+		tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL);
 	}
 
 	if (tok != ']') {
@@ -1353,23 +1380,25 @@ imapx_parse_section (CamelIMAPXStream *is, GError **error)
 }
 
 static guint64
-imapx_parse_modseq (CamelIMAPXStream *is, GError **error)
+imapx_parse_modseq (CamelIMAPXStream *is,
+                    GCancellable *cancellable,
+                    GError **error)
 {
 	guint64 ret;
 	gint tok;
 	guint len;
 	guchar *token;
 
-	tok = camel_imapx_stream_token (is, &token, &len, NULL);
+	tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL);
 	if (tok != '(') {
 		g_set_error (error, CAMEL_IMAPX_ERROR, 1, "fetch: expecting '('");
 		return 0;
 	}
-	ret = camel_imapx_stream_number (is, error);
+	ret = camel_imapx_stream_number (is, cancellable, error);
 	if (ret == 0)
 		return 0;
 
-	tok = camel_imapx_stream_token (is, &token, &len, NULL);
+	tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL);
 	if (tok != ')') {
 		g_set_error (error, CAMEL_IMAPX_ERROR, 1, "fetch: expecting '('");
 		return 0;
@@ -1417,17 +1446,17 @@ imapx_dump_fetch (struct _fetch_info *finfo)
 	sout = camel_stream_fs_new_with_fd (fd);
 	if (finfo->body) {
 		camel_stream_printf(sout, "Body content:\n");
-		camel_stream_write_to_stream (finfo->body, sout, NULL);
+		camel_stream_write_to_stream (finfo->body, sout, NULL, NULL);
 		camel_stream_reset (finfo->body, NULL);
 	}
 	if (finfo->text) {
 		camel_stream_printf(sout, "Text content:\n");
-		camel_stream_write_to_stream (finfo->text, sout, NULL);
+		camel_stream_write_to_stream (finfo->text, sout, NULL, NULL);
 		camel_stream_reset (finfo->text, NULL);
 	}
 	if (finfo->header) {
 		camel_stream_printf(sout, "Header content:\n");
-		camel_stream_write_to_stream (finfo->header, sout, NULL);
+		camel_stream_write_to_stream (finfo->header, sout, NULL, NULL);
 		camel_stream_reset (finfo->header, NULL);
 	}
 	if (finfo->minfo) {
@@ -1454,7 +1483,9 @@ imapx_dump_fetch (struct _fetch_info *finfo)
 }
 
 struct _fetch_info *
-imapx_parse_fetch (CamelIMAPXStream *is, GError **error)
+imapx_parse_fetch (CamelIMAPXStream *is,
+                   GCancellable *cancellable,
+                   GError **error)
 {
 	gint tok;
 	guint len;
@@ -1463,14 +1494,14 @@ imapx_parse_fetch (CamelIMAPXStream *is, GError **error)
 
 	finfo = g_malloc0 (sizeof (*finfo));
 
-	tok = camel_imapx_stream_token (is, &token, &len, NULL);
+	tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL);
 	if (tok != '(') {
 		g_set_error (error, CAMEL_IMAPX_ERROR, 1, "fetch: expecting '('");
 		g_free (finfo);
 		return NULL;
 	}
 
-	while ((tok = camel_imapx_stream_token (is, &token, &len, NULL)) == IMAPX_TOK_TOKEN) {
+	while ((tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL)) == IMAPX_TOK_TOKEN) {
 
 		p = token;
 		while ((c=*p))
@@ -1478,55 +1509,55 @@ imapx_parse_fetch (CamelIMAPXStream *is, GError **error)
 
 		switch (imapx_tokenise ((gchar *) token, len)) {
 			case IMAPX_ENVELOPE:
-				finfo->minfo = imapx_parse_envelope (is, NULL);
+				finfo->minfo = imapx_parse_envelope (is, cancellable, NULL);
 				finfo->got |= FETCH_MINFO;
 				break;
 			case IMAPX_FLAGS:
-				imapx_parse_flags (is, &finfo->flags, &finfo->user_flags, NULL);
+				imapx_parse_flags (is, &finfo->flags, &finfo->user_flags, cancellable, NULL);
 				finfo->got |= FETCH_FLAGS;
 				break;
 			case IMAPX_INTERNALDATE:
-				camel_imapx_stream_nstring (is, &token, NULL);
+				camel_imapx_stream_nstring (is, &token, cancellable, NULL);
 				/* TODO: convert to camel format? */
 				finfo->date = g_strdup ((gchar *) token);
 				finfo->got |= FETCH_DATE;
 				break;
 			case IMAPX_RFC822_HEADER:
-				camel_imapx_stream_nstring_stream (is, &finfo->header, NULL);
+				camel_imapx_stream_nstring_stream (is, &finfo->header, cancellable, NULL);
 				finfo->got |= FETCH_HEADER;
 				break;
 			case IMAPX_RFC822_TEXT:
-				camel_imapx_stream_nstring_stream (is, &finfo->text, NULL);
+				camel_imapx_stream_nstring_stream (is, &finfo->text, cancellable, NULL);
 				finfo->got |= FETCH_TEXT;
 				break;
 			case IMAPX_RFC822_SIZE:
-				finfo->size = camel_imapx_stream_number (is, NULL);
+				finfo->size = camel_imapx_stream_number (is, cancellable, NULL);
 				finfo->got |= FETCH_SIZE;
 				break;
 			case IMAPX_BODYSTRUCTURE:
-				finfo->cinfo = imapx_parse_body (is, NULL);
+				finfo->cinfo = imapx_parse_body (is, cancellable, NULL);
 				finfo->got |= FETCH_CINFO;
 				break;
 			case IMAPX_MODSEQ:
-				finfo->modseq = imapx_parse_modseq (is, NULL);
+				finfo->modseq = imapx_parse_modseq (is, cancellable, NULL);
 				finfo->got |= FETCH_MODSEQ;
 				break;
 			case IMAPX_BODY:
-				tok = camel_imapx_stream_token (is, &token, &len, NULL);
+				tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL);
 				camel_imapx_stream_ungettoken (is, tok, token, len);
 				if (tok == '(') {
-					finfo->cinfo = imapx_parse_body (is, NULL);
+					finfo->cinfo = imapx_parse_body (is, cancellable, NULL);
 					finfo->got |= FETCH_CINFO;
 				} else if (tok == '[') {
-					finfo->section = imapx_parse_section (is, NULL);
+					finfo->section = imapx_parse_section (is, cancellable, NULL);
 					finfo->got |= FETCH_SECTION;
-					tok = camel_imapx_stream_token (is, &token, &len, NULL);
+					tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL);
 					if (token[0] == '<') {
 						finfo->offset = strtoul ((gchar *) token+1, NULL, 10);
 					} else {
 						camel_imapx_stream_ungettoken (is, tok, token, len);
 					}
-					camel_imapx_stream_nstring_stream (is, &finfo->body, NULL);
+					camel_imapx_stream_nstring_stream (is, &finfo->body, cancellable, NULL);
 					finfo->got |= FETCH_BODY;
 				} else {
 					g_set_error (error, CAMEL_IMAPX_ERROR, 1, "unknown body response");
@@ -1535,7 +1566,7 @@ imapx_parse_fetch (CamelIMAPXStream *is, GError **error)
 				}
 				break;
 			case IMAPX_UID:
-				tok = camel_imapx_stream_token (is, &token, &len, NULL);
+				tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL);
 				if (tok != IMAPX_TOK_INT) {
 					g_set_error (error, CAMEL_IMAPX_ERROR, 1, "uid not integer");
 				}
@@ -1560,7 +1591,9 @@ imapx_parse_fetch (CamelIMAPXStream *is, GError **error)
 }
 
 struct _state_info *
-imapx_parse_status_info (struct _CamelIMAPXStream *is, GError **error)
+imapx_parse_status_info (CamelIMAPXStream *is,
+                         GCancellable *cancellable,
+                         GError **error)
 {
 	struct _state_info *sinfo;
 	gint tok;
@@ -1570,38 +1603,38 @@ imapx_parse_status_info (struct _CamelIMAPXStream *is, GError **error)
 	sinfo = g_malloc0 (sizeof (*sinfo));
 
 	/* skip the folder name */
-	if (camel_imapx_stream_astring (is, &token, error)) {
+	if (camel_imapx_stream_astring (is, &token, cancellable, error)) {
 		g_free (sinfo);
 		return NULL;
 	}
 	sinfo->name = camel_utf7_utf8 ((gchar *)token);
 
-	tok = camel_imapx_stream_token (is, &token, &len, NULL);
+	tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL);
 	if (tok != '(') {
 		g_set_error (error, CAMEL_IMAPX_ERROR, 1, "parse status info: expecting '('");
 		g_free (sinfo);
 		return NULL;
 	}
 
-	while ((tok = camel_imapx_stream_token (is, &token, &len, NULL)) == IMAPX_TOK_TOKEN) {
+	while ((tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL)) == IMAPX_TOK_TOKEN) {
 		switch (imapx_tokenise ((gchar *) token, len)) {
 			case IMAPX_MESSAGES:
-				sinfo->messages = camel_imapx_stream_number (is, NULL);
+				sinfo->messages = camel_imapx_stream_number (is, cancellable, NULL);
 				break;
 			case IMAPX_RECENT:
-				sinfo->recent = camel_imapx_stream_number (is, NULL);
+				sinfo->recent = camel_imapx_stream_number (is, cancellable, NULL);
 				break;
 			case IMAPX_UIDNEXT:
-				sinfo->uidnext = camel_imapx_stream_number (is, NULL);
+				sinfo->uidnext = camel_imapx_stream_number (is, cancellable, NULL);
 				break;
 			case IMAPX_UIDVALIDITY:
-				sinfo->uidvalidity = camel_imapx_stream_number (is, NULL);
+				sinfo->uidvalidity = camel_imapx_stream_number (is, cancellable, NULL);
 				break;
 			case IMAPX_UNSEEN:
-				sinfo->unseen = camel_imapx_stream_number (is, NULL);
+				sinfo->unseen = camel_imapx_stream_number (is, cancellable, NULL);
 				break;
 			case IMAPX_HIGHESTMODSEQ:
-				sinfo->highestmodseq = camel_imapx_stream_number (is, NULL);
+				sinfo->highestmodseq = camel_imapx_stream_number (is, cancellable, NULL);
 				break;
 			case IMAPX_NOMODSEQ:
 			break;
@@ -1631,7 +1664,9 @@ generate_uids_from_sequence (GPtrArray *uids, guint32 begin_uid, guint32 end_uid
 }
 
 GPtrArray *
-imapx_parse_uids (CamelIMAPXStream *is, GError **error)
+imapx_parse_uids (CamelIMAPXStream *is,
+                  GCancellable *cancellable,
+                  GError **error)
 {
 	GPtrArray *uids = g_ptr_array_new ();
 	guchar *token;
@@ -1639,7 +1674,7 @@ imapx_parse_uids (CamelIMAPXStream *is, GError **error)
 	guint len, str_len;
 	gint tok, i;
 
-	tok = camel_imapx_stream_token (is, &token, &len, error);
+	tok = camel_imapx_stream_token (is, &token, &len, cancellable, error);
 	if (tok < 0)
 		return NULL;
 
@@ -1668,7 +1703,9 @@ imapx_parse_uids (CamelIMAPXStream *is, GError **error)
 /* rfc 2060 section 7.1 Status Responses */
 /* shoudl this start after [ or before the [? token_unget anyone? */
 struct _status_info *
-imapx_parse_status (CamelIMAPXStream *is, GError **error)
+imapx_parse_status (CamelIMAPXStream *is,
+                    GCancellable *cancellable,
+                    GError **error)
 {
 	gint tok;
 	guint len;
@@ -1677,7 +1714,7 @@ imapx_parse_status (CamelIMAPXStream *is, GError **error)
 
 	sinfo = g_malloc0 (sizeof (*sinfo));
 
-	camel_imapx_stream_atom (is, &token, &len, NULL);
+	camel_imapx_stream_atom (is, &token, &len, cancellable, NULL);
 
 	/*
 	   resp_cond_auth  ::= ("OK" / "PREAUTH") SPACE resp_text
@@ -1703,9 +1740,9 @@ imapx_parse_status (CamelIMAPXStream *is, GError **error)
 			return NULL;
 	}
 
-	tok = camel_imapx_stream_token (is, &token, &len, NULL);
+	tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL);
 	if (tok == '[') {
-		camel_imapx_stream_atom (is, &token, &len, NULL);
+		camel_imapx_stream_atom (is, &token, &len, cancellable, NULL);
 		sinfo->condition = imapx_tokenise ((gchar *) token, len);
 
 		/* parse any details */
@@ -1718,39 +1755,39 @@ imapx_parse_status (CamelIMAPXStream *is, GError **error)
 			case IMAPX_CLOSED:
 				break;
 			case IMAPX_APPENDUID:
-				sinfo->u.appenduid.uidvalidity = camel_imapx_stream_number (is, NULL);
-				sinfo->u.appenduid.uid = camel_imapx_stream_number (is, NULL);
+				sinfo->u.appenduid.uidvalidity = camel_imapx_stream_number (is, cancellable, NULL);
+				sinfo->u.appenduid.uid = camel_imapx_stream_number (is, cancellable, NULL);
 				break;
 			case IMAPX_COPYUID:
-				sinfo->u.copyuid.uidvalidity = camel_imapx_stream_number (is, NULL);
-				sinfo->u.copyuid.uids = imapx_parse_uids (is, NULL);
-				sinfo->u.copyuid.copied_uids = imapx_parse_uids (is, NULL);
+				sinfo->u.copyuid.uidvalidity = camel_imapx_stream_number (is, cancellable, NULL);
+				sinfo->u.copyuid.uids = imapx_parse_uids (is, cancellable, NULL);
+				sinfo->u.copyuid.copied_uids = imapx_parse_uids (is, cancellable, NULL);
 				break;
 			case IMAPX_NEWNAME:
 				/* the rfc doesn't specify the bnf for this */
-				camel_imapx_stream_astring (is, &token, NULL);
+				camel_imapx_stream_astring (is, &token, cancellable, NULL);
 				sinfo->u.newname.oldname = g_strdup ((gchar *) token);
-				camel_imapx_stream_astring (is, &token, NULL);
+				camel_imapx_stream_astring (is, &token, cancellable, NULL);
 				sinfo->u.newname.newname = g_strdup ((gchar *) token);
 				break;
 			case IMAPX_PERMANENTFLAGS:
 				/* we only care about \* for permanent flags, not user flags */
-				imapx_parse_flags (is, &sinfo->u.permanentflags, NULL, NULL);
+				imapx_parse_flags (is, &sinfo->u.permanentflags, NULL, cancellable, NULL);
 				break;
 			case IMAPX_UIDVALIDITY:
-				sinfo->u.uidvalidity = camel_imapx_stream_number (is, NULL);
+				sinfo->u.uidvalidity = camel_imapx_stream_number (is, cancellable, NULL);
 				break;
 			case IMAPX_UIDNEXT:
-				sinfo->u.uidnext = camel_imapx_stream_number (is, NULL);
+				sinfo->u.uidnext = camel_imapx_stream_number (is, cancellable, NULL);
 				break;
 			case IMAPX_UNSEEN:
-				sinfo->u.unseen = camel_imapx_stream_number (is, NULL);
+				sinfo->u.unseen = camel_imapx_stream_number (is, cancellable, NULL);
 				break;
 			case IMAPX_HIGHESTMODSEQ:
-				sinfo->u.highestmodseq = camel_imapx_stream_number (is, NULL);
+				sinfo->u.highestmodseq = camel_imapx_stream_number (is, cancellable, NULL);
 				break;
 			case IMAPX_CAPABILITY:
-				sinfo->u.cinfo = imapx_parse_capability (is, NULL);
+				sinfo->u.cinfo = imapx_parse_capability (is, cancellable, NULL);
 				break;
 			default:
 				sinfo->condition = IMAPX_UNKNOWN;
@@ -1759,7 +1796,7 @@ imapx_parse_status (CamelIMAPXStream *is, GError **error)
 
 		/* ignore anything we dont know about */
 		do {
-			tok = camel_imapx_stream_token (is, &token, &len, NULL);
+			tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL);
 			if (tok == '\n' || tok < 0) {
 				g_set_error (error, CAMEL_IMAPX_ERROR, 1, "server response truncated");
 				imapx_free_status (sinfo);
@@ -1771,7 +1808,7 @@ imapx_parse_status (CamelIMAPXStream *is, GError **error)
 	}
 
 	/* and take the human readable response */
-	camel_imapx_stream_text (is, (guchar **)&sinfo->text, NULL);
+	camel_imapx_stream_text (is, (guchar **)&sinfo->text, cancellable, NULL);
 
 	return sinfo;
 }
@@ -1833,7 +1870,9 @@ static struct {
 };
 
 struct _list_info *
-imapx_parse_list (CamelIMAPXStream *is, GError **error)
+imapx_parse_list (CamelIMAPXStream *is,
+                  GCancellable *cancellable,
+                  GError **error)
 /* throws io, parse */
 {
 	gint tok, i;
@@ -1847,14 +1886,14 @@ imapx_parse_list (CamelIMAPXStream *is, GError **error)
 	   "\Noselect" / "\Unmarked" / flag_extension) ")"
 	   SPACE (<"> QUOTED_CHAR <"> / nil) SPACE mailbox */
 
-	tok = camel_imapx_stream_token (is, &token, &len, NULL);
+	tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL);
 	if (tok != '(') {
 		g_set_error (error, CAMEL_IMAPX_ERROR, 1, "list: expecting '('");
 		g_free (linfo);
 		return NULL;
 	}
 
-	while ((tok = camel_imapx_stream_token (is, &token, &len, NULL)) != ')') {
+	while ((tok = camel_imapx_stream_token (is, &token, &len, cancellable, NULL)) != ')') {
 		if (tok == IMAPX_TOK_STRING || tok == IMAPX_TOK_TOKEN) {
 			p = token;
 			while ((c=*p))
@@ -1869,9 +1908,9 @@ imapx_parse_list (CamelIMAPXStream *is, GError **error)
 		}
 	}
 
-	camel_imapx_stream_nstring (is, &token, NULL);
+	camel_imapx_stream_nstring (is, &token, cancellable, NULL);
 	linfo->separator = token?*token:0;
-	camel_imapx_stream_astring (is, &token, NULL);
+	camel_imapx_stream_astring (is, &token, cancellable, NULL);
 	linfo->name = camel_utf7_utf8 ((gchar *) token);
 
 	return linfo;
diff --git a/camel/providers/imapx/camel-imapx-utils.h b/camel/providers/imapx/camel-imapx-utils.h
index ac19685..baa23cf 100644
--- a/camel/providers/imapx/camel-imapx-utils.h
+++ b/camel/providers/imapx/camel-imapx-utils.h
@@ -84,9 +84,9 @@ enum {
 
 /* ********************************************************************** */
 
-GPtrArray *imapx_parse_uids (struct _CamelIMAPXStream *is, GError **error);
-void imapx_parse_flags (struct _CamelIMAPXStream *stream, guint32 *flagsp, struct _CamelFlag **user_flagsp, GError **error);
-void imapx_write_flags (CamelStream *stream, guint32 flags, struct _CamelFlag *user_flags, GError **error);
+GPtrArray *imapx_parse_uids (struct _CamelIMAPXStream *is, GCancellable *cancellable, GError **error);
+void imapx_parse_flags (struct _CamelIMAPXStream *stream, guint32 *flagsp, struct _CamelFlag **user_flagsp, GCancellable *cancellable, GError **error);
+void imapx_write_flags (CamelStream *stream, guint32 flags, struct _CamelFlag *user_flags, GCancellable *cancellable, GError **error);
 gboolean imapx_update_message_info_flags (CamelMessageInfo *info, guint32 server_flags, CamelFlag *server_user_flags, CamelFolder *folder, gboolean unsolicited);
 void imapx_set_message_info_flags_for_new_message (CamelMessageInfo *info, guint32 server_flags, CamelFlag *server_user_flags,
 							CamelFolder *folder);
@@ -114,16 +114,16 @@ struct _capability_info {
 	GHashTable *auth_types;
 };
 
-struct _capability_info *imapx_parse_capability (struct _CamelIMAPXStream *stream, GError **error);
+struct _capability_info *imapx_parse_capability (struct _CamelIMAPXStream *stream, GCancellable *cancellable, GError **error);
 void imapx_free_capability (struct _capability_info *);
 
-gboolean imapx_parse_param_list (struct _CamelIMAPXStream *is, struct _camel_header_param **plist, GError **error) /* IO,PARSE */;
-struct _CamelContentDisposition *imapx_parse_ext_optional (struct _CamelIMAPXStream *is, GError **error) /* IO,PARSE */;
-struct _CamelMessageContentInfo *imapx_parse_body_fields (struct _CamelIMAPXStream *is, GError **error) /* IO,PARSE */;
-struct _camel_header_address *imapx_parse_address_list (struct _CamelIMAPXStream *is, GError **error) /* IO,PARSE */;
-struct _CamelMessageInfo *imapx_parse_envelope (struct _CamelIMAPXStream *is, GError **error) /* IO, PARSE */;
-struct _CamelMessageContentInfo *imapx_parse_body (struct _CamelIMAPXStream *is, GError **error) /* IO,PARSE */;
-gchar *imapx_parse_section (struct _CamelIMAPXStream *is, GError **error) /* IO,PARSE */;
+gboolean imapx_parse_param_list (struct _CamelIMAPXStream *is, struct _camel_header_param **plist, GCancellable *cancellable, GError **error) /* IO,PARSE */;
+struct _CamelContentDisposition *imapx_parse_ext_optional (struct _CamelIMAPXStream *is, GCancellable *cancellable, GError **error) /* IO,PARSE */;
+struct _CamelMessageContentInfo *imapx_parse_body_fields (struct _CamelIMAPXStream *is, GCancellable *cancellable, GError **error) /* IO,PARSE */;
+struct _camel_header_address *imapx_parse_address_list (struct _CamelIMAPXStream *is, GCancellable *cancellable, GError **error) /* IO,PARSE */;
+struct _CamelMessageInfo *imapx_parse_envelope (struct _CamelIMAPXStream *is, GCancellable *cancellable, GError **error) /* IO, PARSE */;
+struct _CamelMessageContentInfo *imapx_parse_body (struct _CamelIMAPXStream *is, GCancellable *cancellable, GError **error) /* IO,PARSE */;
+gchar *imapx_parse_section (struct _CamelIMAPXStream *is, GCancellable *cancellable, GError **error) /* IO,PARSE */;
 void imapx_free_body (struct _CamelMessageContentInfo *cinfo);
 
 /* ********************************************************************** */
@@ -159,7 +159,7 @@ struct _fetch_info {
 #define FETCH_UID (1<<10)
 #define FETCH_MODSEQ (1<<11)
 
-struct _fetch_info *imapx_parse_fetch (struct _CamelIMAPXStream *is, GError **error);
+struct _fetch_info *imapx_parse_fetch (struct _CamelIMAPXStream *is, GCancellable *cancellable, GError **error);
 void imapx_free_fetch (struct _fetch_info *finfo);
 void imapx_dump_fetch (struct _fetch_info *finfo);
 
@@ -194,7 +194,7 @@ struct _status_info {
 	gchar *text;
 };
 
-struct _status_info *imapx_parse_status (struct _CamelIMAPXStream *is, GError **error);
+struct _status_info *imapx_parse_status (struct _CamelIMAPXStream *is, GCancellable *cancellable, GError **error);
 struct _status_info *imapx_copy_status (struct _status_info *sinfo);
 void imapx_free_status (struct _status_info *sinfo);
 
@@ -211,7 +211,7 @@ struct _state_info {
 };
 
 /* use g_free to free the return value */
-struct _state_info *imapx_parse_status_info (struct _CamelIMAPXStream *is, GError **error);
+struct _state_info *imapx_parse_status_info (struct _CamelIMAPXStream *is, GCancellable *cancellable, GError **error);
 
 /* ********************************************************************** */
 
@@ -223,7 +223,7 @@ struct _list_info {
 	gchar *name;
 };
 
-struct _list_info *imapx_parse_list (struct _CamelIMAPXStream *is, GError **error);
+struct _list_info *imapx_parse_list (struct _CamelIMAPXStream *is, GCancellable *cancellable, GError **error);
 gchar *imapx_list_get_path (struct _list_info *li);
 void imapx_free_list (struct _list_info *linfo);
 
@@ -286,7 +286,7 @@ gchar *imapx_concat (struct _CamelIMAPXStore *imapx_store, const gchar *prefix,
 gchar * imapx_get_temp_uid (void);
 
 void camel_imapx_namespace_list_clear (struct _CamelIMAPXNamespaceList *nsl);
-struct _CamelIMAPXNamespaceList * imapx_parse_namespace_list (struct _CamelIMAPXStream *stream, GError **error);
+struct _CamelIMAPXNamespaceList * imapx_parse_namespace_list (struct _CamelIMAPXStream *stream, GCancellable *cancellable, GError **error);
 struct _CamelIMAPXNamespaceList *camel_imapx_namespace_list_copy (const struct _CamelIMAPXNamespaceList *nsl);
 
 #endif
diff --git a/camel/providers/imapx/test-imapx.c b/camel/providers/imapx/test-imapx.c
index ede8d65..9c154ae 100644
--- a/camel/providers/imapx/test-imapx.c
+++ b/camel/providers/imapx/test-imapx.c
@@ -47,9 +47,11 @@ main (gint argc, gchar *argv[])
 	service = camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, NULL);
 	camel_service_connect (service, NULL);
 
-	camel_store_get_folder_info ((CamelStore *)service, "", 3, NULL);
-	folder = camel_store_get_folder ((CamelStore *)service, "INBOX", 0, NULL);
-	camel_folder_refresh_info (folder, NULL);
+	camel_store_get_folder_info (
+		CAMEL_STORE (service), "", 3, NULL, NULL);
+	folder = camel_store_get_folder (
+		CAMEL_STORE (service), "INBOX", 0, NULL, NULL);
+	camel_folder_refresh_info (folder, NULL, NULL);
 
 	while (1)
 	{
diff --git a/camel/providers/local/camel-local-folder.c b/camel/providers/local/camel-local-folder.c
index 0f2b543..cab3a7b 100644
--- a/camel/providers/local/camel-local-folder.c
+++ b/camel/providers/local/camel-local-folder.c
@@ -62,23 +62,6 @@ enum {
 	PROP_INDEX_BODY = 0x2400
 };
 
-static gint local_lock (CamelLocalFolder *lf, CamelLockType type, GError **error);
-static void local_unlock (CamelLocalFolder *lf);
-
-static gboolean local_refresh_info (CamelFolder *folder, GError **error);
-
-static gboolean local_sync (CamelFolder *folder, gboolean expunge, GError **error);
-static gboolean local_expunge (CamelFolder *folder, GError **error);
-
-static GPtrArray *local_search_by_expression (CamelFolder *folder, const gchar *expression, GError **error);
-static guint32 local_count_by_expression (CamelFolder *folder, const gchar *expression, GError **error);
-static GPtrArray *local_search_by_uids (CamelFolder *folder, const gchar *expression, GPtrArray *uids, GError **error);
-static void local_search_free (CamelFolder *folder, GPtrArray * result);
-static GPtrArray * local_get_uncached_uids (CamelFolder *folder, GPtrArray * uids, GError **error);
-
-static void local_delete (CamelFolder *folder);
-static void local_rename (CamelFolder *folder, const gchar *newname);
-
 G_DEFINE_TYPE (CamelLocalFolder, camel_local_folder, CAMEL_TYPE_FOLDER)
 
 static void
@@ -127,7 +110,7 @@ local_folder_dispose (GObject *object)
 	if (folder->summary != NULL) {
 		camel_local_summary_sync (
 			CAMEL_LOCAL_SUMMARY (folder->summary),
-			FALSE, local_folder->changes, NULL);
+			FALSE, local_folder->changes, NULL, NULL);
 		g_object_unref (folder->summary);
 		folder->summary = NULL;
 	}
@@ -233,6 +216,220 @@ local_folder_constructed (GObject *object)
 	g_free (path);
 }
 
+static gboolean
+local_folder_refresh_info (CamelFolder *folder,
+                           GCancellable *cancellable,
+                           GError **error)
+{
+	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
+
+	if (camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, cancellable, error) == -1)
+		return FALSE;
+
+	if (camel_folder_change_info_changed (lf->changes)) {
+		camel_folder_changed (folder, lf->changes);
+		camel_folder_change_info_clear (lf->changes);
+	}
+
+	return TRUE;
+}
+
+static gboolean
+local_folder_sync (CamelFolder *folder,
+                   gboolean expunge,
+                   GCancellable *cancellable,
+                   GError **error)
+{
+	CamelLocalFolder *lf = CAMEL_LOCAL_FOLDER (folder);
+	gboolean success;
+
+	d(printf("local sync '%s' , expunge=%s\n", folder->full_name, expunge?"true":"false"));
+
+	if (camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1)
+		return FALSE;
+
+	camel_object_state_write (CAMEL_OBJECT (lf));
+
+	/* if sync fails, we'll pass it up on exit through ex */
+	success = (camel_local_summary_sync (
+		(CamelLocalSummary *)folder->summary,
+		expunge, lf->changes, cancellable, error) == 0);
+	camel_local_folder_unlock (lf);
+
+	if (camel_folder_change_info_changed (lf->changes)) {
+		camel_folder_changed (folder, lf->changes);
+		camel_folder_change_info_clear (lf->changes);
+	}
+
+	return success;
+}
+
+static gboolean
+local_folder_expunge (CamelFolder *folder,
+                      GCancellable *cancellable,
+                      GError **error)
+{
+	/* Just do a sync with expunge, serves the same purpose */
+	/* call the callback directly, to avoid locking problems */
+	return CAMEL_FOLDER_GET_CLASS (folder)->sync (
+		folder, TRUE, cancellable, error);
+}
+
+static GPtrArray *
+local_folder_search_by_expression (CamelFolder *folder,
+                                   const gchar *expression,
+                                   GError **error)
+{
+	CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER (folder);
+	GPtrArray *matches;
+
+	CAMEL_LOCAL_FOLDER_LOCK (folder, search_lock);
+
+	if (local_folder->search == NULL)
+		local_folder->search = camel_folder_search_new ();
+
+	camel_folder_search_set_folder (local_folder->search, folder);
+	camel_folder_search_set_body_index (local_folder->search, local_folder->index);
+	matches = camel_folder_search_search (local_folder->search, expression, NULL, error);
+
+	CAMEL_LOCAL_FOLDER_UNLOCK (folder, search_lock);
+
+	return matches;
+}
+
+static GPtrArray *
+local_folder_search_by_uids (CamelFolder *folder,
+                             const gchar *expression,
+                             GPtrArray *uids,
+                             GError **error)
+{
+	CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER (folder);
+	GPtrArray *matches;
+
+	if (uids->len == 0)
+		return g_ptr_array_new ();
+
+	CAMEL_LOCAL_FOLDER_LOCK (folder, search_lock);
+
+	if (local_folder->search == NULL)
+		local_folder->search = camel_folder_search_new ();
+
+	camel_folder_search_set_folder (local_folder->search, folder);
+	camel_folder_search_set_body_index (local_folder->search, local_folder->index);
+	matches = camel_folder_search_search (local_folder->search, expression, uids, error);
+
+	CAMEL_LOCAL_FOLDER_UNLOCK (folder, search_lock);
+
+	return matches;
+}
+
+static void
+local_folder_search_free (CamelFolder *folder,
+                          GPtrArray *result)
+{
+	CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER (folder);
+
+	/* we need to lock this free because of the way search_free_result works */
+	/* FIXME: put the lock inside search_free_result */
+	CAMEL_LOCAL_FOLDER_LOCK (folder, search_lock);
+
+	camel_folder_search_free_result (local_folder->search, result);
+
+	CAMEL_LOCAL_FOLDER_UNLOCK (folder, search_lock);
+}
+
+static void
+local_folder_delete (CamelFolder *folder)
+{
+	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
+
+	if (lf->index)
+		camel_index_delete (lf->index);
+
+	CAMEL_FOLDER_CLASS (camel_local_folder_parent_class)->delete (folder);
+}
+
+static void
+local_folder_rename (CamelFolder *folder,
+                     const gchar *newname)
+{
+	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
+	gchar *statepath;
+	CamelLocalStore *ls;
+	CamelStore *parent_store;
+
+	parent_store = camel_folder_get_parent_store (folder);
+	ls = CAMEL_LOCAL_STORE (parent_store);
+
+	d(printf("renaming local folder paths to '%s'\n", newname));
+
+	/* Sync? */
+
+	g_free (lf->folder_path);
+	g_free (lf->summary_path);
+	g_free (lf->index_path);
+
+	lf->folder_path = camel_local_store_get_full_path (ls, newname);
+	lf->summary_path = camel_local_store_get_meta_path(ls, newname, ".ev-summary");
+	lf->index_path = camel_local_store_get_meta_path(ls, newname, ".ibex");
+	statepath = camel_local_store_get_meta_path(ls, newname, ".cmeta");
+	camel_object_set_state_filename (CAMEL_OBJECT (lf), statepath);
+	g_free (statepath);
+
+	/* FIXME: Poke some internals, sigh */
+	camel_folder_summary_set_filename (folder->summary, lf->summary_path);
+	g_free (((CamelLocalSummary *)folder->summary)->folder_path);
+	((CamelLocalSummary *)folder->summary)->folder_path = g_strdup (lf->folder_path);
+
+	CAMEL_FOLDER_CLASS (camel_local_folder_parent_class)->rename (folder, newname);
+}
+
+static guint32
+local_folder_count_by_expression (CamelFolder *folder,
+                                  const gchar *expression,
+                                  GError **error)
+{
+	CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER (folder);
+	gint matches;
+
+	CAMEL_LOCAL_FOLDER_LOCK (folder, search_lock);
+
+	if (local_folder->search == NULL)
+		local_folder->search = camel_folder_search_new ();
+
+	camel_folder_search_set_folder (local_folder->search, folder);
+	camel_folder_search_set_body_index (local_folder->search, local_folder->index);
+	matches = camel_folder_search_count (local_folder->search, expression, error);
+
+	CAMEL_LOCAL_FOLDER_UNLOCK (folder, search_lock);
+
+	return matches;
+}
+
+static GPtrArray *
+local_folder_get_uncached_uids (CamelFolder *folder,
+                                GPtrArray *uids,
+                                GError **error)
+{
+	/* By default, we would have everything local.
+	 * No need to fetch from anywhere. */
+	return g_ptr_array_new ();
+}
+
+static gint
+local_folder_lock (CamelLocalFolder *lf,
+                   CamelLockType type,
+                   GError **error)
+{
+	return 0;
+}
+
+static void
+local_folder_unlock (CamelLocalFolder *lf)
+{
+	/* nothing */
+}
+
 static void
 camel_local_folder_class_init (CamelLocalFolderClass *class)
 {
@@ -249,19 +446,19 @@ camel_local_folder_class_init (CamelLocalFolderClass *class)
 	object_class->constructed = local_folder_constructed;
 
 	folder_class = CAMEL_FOLDER_CLASS (class);
-	folder_class->refresh_info = local_refresh_info;
-	folder_class->sync = local_sync;
-	folder_class->expunge = local_expunge;
-	folder_class->get_uncached_uids = local_get_uncached_uids;
-	folder_class->search_by_expression = local_search_by_expression;
-	folder_class->count_by_expression = local_count_by_expression;
-	folder_class->search_by_uids = local_search_by_uids;
-	folder_class->search_free = local_search_free;
-	folder_class->delete = local_delete;
-	folder_class->rename = local_rename;
-
-	class->lock = local_lock;
-	class->unlock = local_unlock;
+	folder_class->refresh_info = local_folder_refresh_info;
+	folder_class->sync = local_folder_sync;
+	folder_class->expunge = local_folder_expunge;
+	folder_class->search_by_expression = local_folder_search_by_expression;
+	folder_class->search_by_uids = local_folder_search_by_uids;
+	folder_class->search_free = local_folder_search_free;
+	folder_class->delete = local_folder_delete;
+	folder_class->rename = local_folder_rename;
+	folder_class->count_by_expression = local_folder_count_by_expression;
+	folder_class->get_uncached_uids = local_folder_get_uncached_uids;
+
+	class->lock = local_folder_lock;
+	class->unlock = local_folder_unlock;
 
 	g_object_class_install_property (
 		object_class,
@@ -296,7 +493,10 @@ camel_local_folder_init (CamelLocalFolder *local_folder)
 }
 
 CamelLocalFolder *
-camel_local_folder_construct (CamelLocalFolder *lf, guint32 flags, GError **error)
+camel_local_folder_construct (CamelLocalFolder *lf,
+                              guint32 flags,
+                              GCancellable *cancellable,
+                              GError **error)
 {
 	CamelFolder *folder;
 	CamelFolderInfo *fi;
@@ -387,9 +587,9 @@ camel_local_folder_construct (CamelLocalFolder *lf, guint32 flags, GError **erro
 	folder->summary = (CamelFolderSummary *)CAMEL_LOCAL_FOLDER_GET_CLASS (lf)->create_summary (lf, lf->summary_path, lf->folder_path, lf->index);
 	if (!(flags & CAMEL_STORE_IS_MIGRATING) && camel_local_summary_load ((CamelLocalSummary *)folder->summary, forceindex, NULL) == -1) {
 		/* ? */
-		if (camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, error) == 0) {
+		if (camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, cancellable, error) == 0) {
 			/* we sync here so that any hard work setting up the folder isn't lost */
-			if (camel_local_summary_sync ((CamelLocalSummary *)folder->summary, FALSE, lf->changes, error) == -1) {
+			if (camel_local_summary_sync ((CamelLocalSummary *)folder->summary, FALSE, lf->changes, cancellable, error) == -1) {
 				g_object_unref (CAMEL_OBJECT (folder));
 				return NULL;
 			}
@@ -452,7 +652,10 @@ camel_local_folder_set_index_body (CamelLocalFolder *local_folder,
 
 /* lock the folder, may be called repeatedly (with matching unlock calls),
    with type the same or less than the first call */
-gint camel_local_folder_lock (CamelLocalFolder *lf, CamelLockType type, GError **error)
+gint
+camel_local_folder_lock (CamelLocalFolder *lf,
+                         CamelLockType type,
+                         GError **error)
 {
 	if (lf->locked > 0) {
 		/* lets be anal here - its important the code knows what its doing */
@@ -469,7 +672,8 @@ gint camel_local_folder_lock (CamelLocalFolder *lf, CamelLockType type, GError *
 }
 
 /* unlock folder */
-gint camel_local_folder_unlock (CamelLocalFolder *lf)
+gint
+camel_local_folder_unlock (CamelLocalFolder *lf)
 {
 	g_assert (lf->locked>0);
 	lf->locked--;
@@ -479,202 +683,6 @@ gint camel_local_folder_unlock (CamelLocalFolder *lf)
 	return 0;
 }
 
-static gint
-local_lock (CamelLocalFolder *lf, CamelLockType type, GError **error)
-{
-	return 0;
-}
-
-static void
-local_unlock (CamelLocalFolder *lf)
-{
-	/* nothing */
-}
-
-/* for auto-check to work */
-static gboolean
-local_refresh_info (CamelFolder *folder, GError **error)
-{
-	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
-
-	if (camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, error) == -1)
-		return FALSE;
-
-	if (camel_folder_change_info_changed (lf->changes)) {
-		camel_folder_changed (folder, lf->changes);
-		camel_folder_change_info_clear (lf->changes);
-	}
-
-	return TRUE;
-}
-
-static GPtrArray *
-local_get_uncached_uids (CamelFolder *folder, GPtrArray * uids, GError **error)
-{
-	GPtrArray *result = g_ptr_array_new ();
-	/* By default, we would have everything local. No need to fetch from anywhere. */
-	return result;
-}
-
-static gboolean
-local_sync (CamelFolder *folder, gboolean expunge, GError **error)
-{
-	CamelLocalFolder *lf = CAMEL_LOCAL_FOLDER (folder);
-	gboolean success;
-
-	d(printf("local sync '%s' , expunge=%s\n", folder->full_name, expunge?"true":"false"));
-
-	if (camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1)
-		return FALSE;
-
-	camel_object_state_write (CAMEL_OBJECT (lf));
-
-	/* if sync fails, we'll pass it up on exit through ex */
-	success = (camel_local_summary_sync (
-		(CamelLocalSummary *)folder->summary,
-		expunge, lf->changes, error) == 0);
-	camel_local_folder_unlock (lf);
-
-	if (camel_folder_change_info_changed (lf->changes)) {
-		camel_folder_changed (folder, lf->changes);
-		camel_folder_change_info_clear (lf->changes);
-	}
-
-	return success;
-}
-
-static gboolean
-local_expunge (CamelFolder *folder, GError **error)
-{
-	d(printf("expunge\n"));
-
-	/* Just do a sync with expunge, serves the same purpose */
-	/* call the callback directly, to avoid locking problems */
-	return CAMEL_FOLDER_GET_CLASS (folder)->sync (folder, TRUE, error);
-}
-
-static void
-local_delete (CamelFolder *folder)
-{
-	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
-
-	if (lf->index)
-		camel_index_delete (lf->index);
-
-	CAMEL_FOLDER_CLASS (camel_local_folder_parent_class)->delete (folder);
-}
-
-static void
-local_rename (CamelFolder *folder, const gchar *newname)
-{
-	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
-	gchar *statepath;
-	CamelLocalStore *ls;
-	CamelStore *parent_store;
-
-	parent_store = camel_folder_get_parent_store (folder);
-	ls = CAMEL_LOCAL_STORE (parent_store);
-
-	d(printf("renaming local folder paths to '%s'\n", newname));
-
-	/* Sync? */
-
-	g_free (lf->folder_path);
-	g_free (lf->summary_path);
-	g_free (lf->index_path);
-
-	lf->folder_path = camel_local_store_get_full_path (ls, newname);
-	lf->summary_path = camel_local_store_get_meta_path(ls, newname, ".ev-summary");
-	lf->index_path = camel_local_store_get_meta_path(ls, newname, ".ibex");
-	statepath = camel_local_store_get_meta_path(ls, newname, ".cmeta");
-	camel_object_set_state_filename (CAMEL_OBJECT (lf), statepath);
-	g_free (statepath);
-
-	/* FIXME: Poke some internals, sigh */
-	camel_folder_summary_set_filename (folder->summary, lf->summary_path);
-	g_free (((CamelLocalSummary *)folder->summary)->folder_path);
-	((CamelLocalSummary *)folder->summary)->folder_path = g_strdup (lf->folder_path);
-
-	CAMEL_FOLDER_CLASS (camel_local_folder_parent_class)->rename (folder, newname);
-}
-
-static GPtrArray *
-local_search_by_expression (CamelFolder *folder, const gchar *expression, GError **error)
-{
-	CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER (folder);
-	GPtrArray *matches;
-
-	CAMEL_LOCAL_FOLDER_LOCK (folder, search_lock);
-
-	if (local_folder->search == NULL)
-		local_folder->search = camel_folder_search_new ();
-
-	camel_folder_search_set_folder (local_folder->search, folder);
-	camel_folder_search_set_body_index (local_folder->search, local_folder->index);
-	matches = camel_folder_search_search (local_folder->search, expression, NULL, error);
-
-	CAMEL_LOCAL_FOLDER_UNLOCK (folder, search_lock);
-
-	return matches;
-}
-
-static guint32
-local_count_by_expression (CamelFolder *folder, const gchar *expression, GError **error)
-{
-	CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER (folder);
-	gint matches;
-
-	CAMEL_LOCAL_FOLDER_LOCK (folder, search_lock);
-
-	if (local_folder->search == NULL)
-		local_folder->search = camel_folder_search_new ();
-
-	camel_folder_search_set_folder (local_folder->search, folder);
-	camel_folder_search_set_body_index (local_folder->search, local_folder->index);
-	matches = camel_folder_search_count (local_folder->search, expression, error);
-
-	CAMEL_LOCAL_FOLDER_UNLOCK (folder, search_lock);
-
-	return matches;
-}
-
-static GPtrArray *
-local_search_by_uids (CamelFolder *folder, const gchar *expression, GPtrArray *uids, GError **error)
-{
-	CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER (folder);
-	GPtrArray *matches;
-
-	if (uids->len == 0)
-		return g_ptr_array_new ();
-
-	CAMEL_LOCAL_FOLDER_LOCK (folder, search_lock);
-
-	if (local_folder->search == NULL)
-		local_folder->search = camel_folder_search_new ();
-
-	camel_folder_search_set_folder (local_folder->search, folder);
-	camel_folder_search_set_body_index (local_folder->search, local_folder->index);
-	matches = camel_folder_search_search (local_folder->search, expression, uids, error);
-
-	CAMEL_LOCAL_FOLDER_UNLOCK (folder, search_lock);
-
-	return matches;
-}
-
-static void
-local_search_free (CamelFolder *folder, GPtrArray * result)
-{
-	CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER (folder);
-
-	/* we need to lock this free because of the way search_free_result works */
-	/* FIXME: put the lock inside search_free_result */
-	CAMEL_LOCAL_FOLDER_LOCK (folder, search_lock);
-
-	camel_folder_search_free_result (local_folder->search, result);
-
-	CAMEL_LOCAL_FOLDER_UNLOCK (folder, search_lock);
-}
-
 void
 set_cannot_get_message_ex (GError **error, gint err_code, const gchar *msgID, const gchar *folder_path, const gchar *detailErr)
 {
diff --git a/camel/providers/local/camel-local-folder.h b/camel/providers/local/camel-local-folder.h
index 1d3b077..02415dd 100644
--- a/camel/providers/local/camel-local-folder.h
+++ b/camel/providers/local/camel-local-folder.h
@@ -76,13 +76,19 @@ struct _CamelLocalFolderClass {
 	/* Virtual methods */
 
 	/* summary factory, only used at init */
-	CamelLocalSummary *(*create_summary)(CamelLocalFolder *lf, const gchar *path, const gchar *folder, CamelIndex *index);
+	CamelLocalSummary *
+			(*create_summary)	(CamelLocalFolder *lf,
+						 const gchar *path,
+						 const gchar *folder,
+						 CamelIndex *index);
 
 	/* Lock the folder for my operations */
-	gint (*lock)(CamelLocalFolder *, CamelLockType type, GError **error);
+	gint		(*lock)			(CamelLocalFolder *lf,
+						 CamelLockType type,
+						 GError **error);
 
 	/* Unlock the folder for my operations */
-	void (*unlock)(CamelLocalFolder *);
+	void		(*unlock)		(CamelLocalFolder *);
 };
 
 GType		camel_local_folder_get_type	(void);
@@ -91,6 +97,7 @@ GType		camel_local_folder_get_type	(void);
 CamelLocalFolder *
 		camel_local_folder_construct	(CamelLocalFolder *local_folder,
 						 guint32 flags,
+						 GCancellable *cancellable,
 						 GError **error);
 gboolean	camel_local_folder_get_index_body
 						(CamelLocalFolder *local_folder);
diff --git a/camel/providers/local/camel-local-store.c b/camel/providers/local/camel-local-store.c
index 5f09297..d3ef901 100644
--- a/camel/providers/local/camel-local-store.c
+++ b/camel/providers/local/camel-local-store.c
@@ -38,15 +38,15 @@
 #define d(x)
 
 static gboolean construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, GError **error);
-static CamelFolder *get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError **error);
+static CamelFolder *get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GCancellable *cancellable, GError **error);
 static gchar *get_name (CamelService *service, gboolean brief);
-static CamelFolder *local_get_inbox (CamelStore *store, GError **error);
-static CamelFolder *local_get_junk (CamelStore *store, GError **error);
-static CamelFolder *local_get_trash (CamelStore *store, GError **error);
-static CamelFolderInfo *get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GError **error);
-static gboolean delete_folder (CamelStore *store, const gchar *folder_name, GError **error);
-static gboolean rename_folder (CamelStore *store, const gchar *old, const gchar *new, GError **error);
-static CamelFolderInfo *create_folder (CamelStore *store, const gchar *parent_name, const gchar *folder_name, GError **error);
+static CamelFolder *local_get_inbox (CamelStore *store, GCancellable *cancellable, GError **error);
+static CamelFolder *local_get_junk (CamelStore *store, GCancellable *cancellable, GError **error);
+static CamelFolder *local_get_trash (CamelStore *store, GCancellable *cancellable, GError **error);
+static CamelFolderInfo *get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GCancellable *cancellable, GError **error);
+static gboolean delete_folder (CamelStore *store, const gchar *folder_name, GCancellable *cancellable, GError **error);
+static gboolean rename_folder (CamelStore *store, const gchar *old, const gchar *new, GCancellable *cancellable, GError **error);
+static CamelFolderInfo *create_folder (CamelStore *store, const gchar *parent_name, const gchar *folder_name, GCancellable *cancellable, GError **error);
 static gboolean local_can_refresh_folder (CamelStore *store, CamelFolderInfo *info, GError **error);
 
 static gchar *local_get_full_path (CamelLocalStore *lf, const gchar *full_name);
@@ -132,7 +132,11 @@ camel_local_store_get_toplevel_dir (CamelLocalStore *store)
 }
 
 static CamelFolder *
-get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError **error)
+get_folder (CamelStore *store,
+            const gchar *folder_name,
+            guint32 flags,
+            GCancellable *cancellable,
+            GError **error)
 {
 	gint len = strlen (((CamelLocalStore *)store)->toplevel_dir);
 	gchar *path = g_alloca (len + 1);
@@ -185,7 +189,9 @@ get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError *
 }
 
 static CamelFolder *
-local_get_inbox (CamelStore *store, GError **error)
+local_get_inbox (CamelStore *store,
+                 GCancellable *cancellable,
+                 GError **error)
 {
 	g_set_error (
 		error, CAMEL_STORE_ERROR,
@@ -197,12 +203,14 @@ local_get_inbox (CamelStore *store, GError **error)
 
 static CamelFolder *
 local_get_trash (CamelStore *store,
+                 GCancellable *cancellable,
                  GError **error)
 {
 	CamelFolder *folder;
 
 	/* Chain up to parent's get_trash() method. */
-	folder = CAMEL_STORE_CLASS (camel_local_store_parent_class)->get_trash (store, error);
+	folder = CAMEL_STORE_CLASS (camel_local_store_parent_class)->
+		get_trash (store, cancellable, error);
 
 	if (folder) {
 		CamelObject *object = CAMEL_OBJECT (folder);
@@ -219,12 +227,14 @@ local_get_trash (CamelStore *store,
 
 static CamelFolder *
 local_get_junk (CamelStore *store,
+                GCancellable *cancellable,
                 GError **error)
 {
 	CamelFolder *folder;
 
 	/* Chain up to parent's get_junk() method. */
-	folder = CAMEL_STORE_CLASS (camel_local_store_parent_class)->get_junk (store, error);
+	folder = CAMEL_STORE_CLASS (camel_local_store_parent_class)->
+		get_junk (store, cancellable, error);
 
 	if (folder) {
 		CamelObject *object = CAMEL_OBJECT (folder);
@@ -251,8 +261,11 @@ get_name (CamelService *service, gboolean brief)
 }
 
 static CamelFolderInfo *
-get_folder_info (CamelStore *store, const gchar *top,
-		 guint32 flags, GError **error)
+get_folder_info (CamelStore *store,
+                 const gchar *top,
+                 guint32 flags,
+                 GCancellable *cancellable,
+                 GError **error)
 {
 	/* FIXME: This is broken, but it corresponds to what was
 	 * there before.
@@ -267,6 +280,7 @@ static CamelFolderInfo *
 create_folder (CamelStore *store,
                const gchar *parent_name,
                const gchar *folder_name,
+               GCancellable *cancellable,
                GError **error)
 {
 	gchar *path = ((CamelLocalStore *)store)->toplevel_dir;
@@ -308,11 +322,11 @@ create_folder (CamelStore *store,
 		name = g_strdup_printf("%s", folder_name);
 
 	folder = CAMEL_STORE_GET_CLASS (store)->get_folder (
-		store, name, CAMEL_STORE_FOLDER_CREATE, error);
+		store, name, CAMEL_STORE_FOLDER_CREATE, cancellable, error);
 	if (folder) {
 		g_object_unref (folder);
 		info = CAMEL_STORE_GET_CLASS (store)->get_folder_info (
-			store, name, 0, error);
+			store, name, 0, cancellable, error);
 	}
 
 	g_free (name);
@@ -369,6 +383,7 @@ static gboolean
 rename_folder (CamelStore *store,
               const gchar *old,
               const gchar *new,
+              GCancellable *cancellable,
               GError **error)
 {
 	gchar *path = CAMEL_LOCAL_STORE (store)->toplevel_dir;
@@ -444,6 +459,7 @@ ibex_failed:
 static gboolean
 delete_folder (CamelStore *store,
                const gchar *folder_name,
+               GCancellable *cancellable,
                GError **error)
 {
 	CamelFolderInfo *fi;
@@ -467,7 +483,7 @@ delete_folder (CamelStore *store,
 	g_free (str);
 
 	str = NULL;
-	if ((lf = camel_store_get_folder (store, folder_name, 0, NULL))) {
+	if ((lf = camel_store_get_folder (store, folder_name, 0, cancellable, NULL))) {
 		CamelObject *object = CAMEL_OBJECT (lf);
 		const gchar *state_filename;
 
diff --git a/camel/providers/local/camel-local-summary.c b/camel/providers/local/camel-local-summary.c
index 28c1f9e..3e13f9f 100644
--- a/camel/providers/local/camel-local-summary.c
+++ b/camel/providers/local/camel-local-summary.c
@@ -55,8 +55,8 @@ static gint local_summary_decode_x_evolution (CamelLocalSummary *cls, const gcha
 static gchar *local_summary_encode_x_evolution (CamelLocalSummary *cls, const CamelLocalMessageInfo *mi);
 
 static gint local_summary_load (CamelLocalSummary *cls, gint forceindex, GError **error);
-static gint local_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GError **error);
-static gint local_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error);
+static gint local_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error);
+static gint local_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error);
 static CamelMessageInfo *local_summary_add (CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, GError **error);
 static gint local_summary_need_index (void);
 
@@ -268,13 +268,14 @@ do_stat_mi (CamelLocalSummary *cls, struct _stat_info *info, CamelMessageInfo *m
 gint
 camel_local_summary_check (CamelLocalSummary *cls,
                            CamelFolderChangeInfo *changeinfo,
+                           GCancellable *cancellable,
                            GError **error)
 {
 	CamelLocalSummaryClass *local_summary_class;
 	gint ret;
 
 	local_summary_class = CAMEL_LOCAL_SUMMARY_GET_CLASS (cls);
-	ret = local_summary_class->check (cls, changeinfo, error);
+	ret = local_summary_class->check (cls, changeinfo, cancellable, error);
 
 #ifdef DOSTATS
 	if (ret != -1) {
@@ -304,13 +305,14 @@ gint
 camel_local_summary_sync (CamelLocalSummary *cls,
                           gboolean expunge,
                           CamelFolderChangeInfo *changeinfo,
+                          GCancellable *cancellable,
                           GError **error)
 {
 	CamelLocalSummaryClass *local_summary_class;
 
 	local_summary_class = CAMEL_LOCAL_SUMMARY_GET_CLASS (cls);
 
-	return local_summary_class->sync (cls, expunge, changeinfo, error);
+	return local_summary_class->sync (cls, expunge, changeinfo, cancellable, error);
 }
 
 CamelMessageInfo *
@@ -416,7 +418,10 @@ camel_local_summary_write_headers (gint fd, struct _camel_header_raw *header, co
 }
 
 static gint
-local_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GError **error)
+local_summary_check (CamelLocalSummary *cls,
+                     CamelFolderChangeInfo *changeinfo,
+                     GCancellable *cancellable,
+                     GError **error)
 {
 	/* FIXME: sync index here ? */
 	return 0;
@@ -426,6 +431,7 @@ static gint
 local_summary_sync (CamelLocalSummary *cls,
                     gboolean expunge,
                     CamelFolderChangeInfo *changeinfo,
+                    GCancellable *cancellable,
                     GError **error)
 {
 	CamelFolderSummary *folder_summary;
@@ -485,7 +491,11 @@ update_summary (CamelFolderSummary *summary, CamelMessageInfoBase *info, CamelMe
 }
 
 static CamelMessageInfo *
-local_summary_add (CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *ci, GError **error)
+local_summary_add (CamelLocalSummary *cls,
+                   CamelMimeMessage *msg,
+                   const CamelMessageInfo *info,
+                   CamelFolderChangeInfo *ci,
+                   GError **error)
 {
 	CamelLocalMessageInfo *mi;
 	CamelFolderSummary *s = (CamelFolderSummary *)cls;
@@ -520,7 +530,7 @@ local_summary_add (CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMes
 		if (mi->info.size == 0) {
 			CamelStreamNull *sn = (CamelStreamNull *)camel_stream_null_new ();
 
-			camel_data_wrapper_write_to_stream ((CamelDataWrapper *)msg, (CamelStream *)sn, NULL);
+			camel_data_wrapper_write_to_stream ((CamelDataWrapper *)msg, (CamelStream *)sn, NULL, NULL);
 			mi->info.size = sn->written;
 			g_object_unref (sn);
 		}
diff --git a/camel/providers/local/camel-local-summary.h b/camel/providers/local/camel-local-summary.h
index d5a7ce8..54be594 100644
--- a/camel/providers/local/camel-local-summary.h
+++ b/camel/providers/local/camel-local-summary.h
@@ -76,8 +76,8 @@ struct _CamelLocalSummaryClass {
 	CamelFolderSummaryClass parent_class;
 
 	gint (*load)(CamelLocalSummary *cls, gint forceindex, GError **error);
-	gint (*check)(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GError **error);
-	gint (*sync)(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error);
+	gint (*check)(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error);
+	gint (*sync)(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error);
 	CamelMessageInfo *(*add)(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, GError **error);
 
 	gchar *(*encode_x_evolution)(CamelLocalSummary *cls, const CamelLocalMessageInfo *info);
@@ -91,9 +91,9 @@ void	camel_local_summary_construct	(CamelLocalSummary *new, const gchar *filenam
 /* load/check the summary */
 gint camel_local_summary_load (CamelLocalSummary *cls, gint forceindex, GError **error);
 /* check for new/removed messages */
-gint camel_local_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *, GError **error);
+gint camel_local_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *, GCancellable *cancellable, GError **error);
 /* perform a folder sync or expunge, if needed */
-gint camel_local_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *, GError **error);
+gint camel_local_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *, GCancellable *cancellable, GError **error);
 /* add a new message to the summary */
 CamelMessageInfo *camel_local_summary_add (CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, GError **error);
 
diff --git a/camel/providers/local/camel-maildir-folder.c b/camel/providers/local/camel-maildir-folder.c
index 934ada9..5281d5a 100644
--- a/camel/providers/local/camel-maildir-folder.c
+++ b/camel/providers/local/camel-maildir-folder.c
@@ -41,89 +41,15 @@
 
 #define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
 
-static CamelLocalSummary *maildir_create_summary (CamelLocalFolder *lf, const gchar *path, const gchar *folder, CamelIndex *index);
-
-static gboolean maildir_append_message (CamelFolder * folder, CamelMimeMessage * message, const CamelMessageInfo *info, gchar **appended_uid, GError **error);
-static CamelMimeMessage *maildir_get_message (CamelFolder * folder, const gchar * uid, GError **error);
-static gchar * maildir_get_filename (CamelFolder *folder, const gchar *uid, GError **error);
-static gint maildir_cmp_uids (CamelFolder *folder, const gchar *uid1, const gchar *uid2);
-static void maildir_sort_uids (CamelFolder *folder, GPtrArray *uids);
-static gboolean maildir_transfer_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *dest, GPtrArray **transferred_uids, gboolean delete_originals, GError **error);
-
 G_DEFINE_TYPE (CamelMaildirFolder, camel_maildir_folder, CAMEL_TYPE_LOCAL_FOLDER)
 
-static void
-camel_maildir_folder_class_init (CamelMaildirFolderClass *class)
-{
-	CamelFolderClass *folder_class;
-	CamelLocalFolderClass *local_folder_class;
-
-	folder_class = CAMEL_FOLDER_CLASS (class);
-	folder_class->append_message = maildir_append_message;
-	folder_class->get_message = maildir_get_message;
-	folder_class->get_filename = maildir_get_filename;
-	folder_class->cmp_uids = maildir_cmp_uids;
-	folder_class->sort_uids = maildir_sort_uids;
-	folder_class->transfer_messages_to = maildir_transfer_messages_to;
-
-	local_folder_class = CAMEL_LOCAL_FOLDER_CLASS (class);
-	local_folder_class->create_summary = maildir_create_summary;
-}
-
-static void
-camel_maildir_folder_init (CamelMaildirFolder *maildir_folder)
-{
-}
-
-CamelFolder *
-camel_maildir_folder_new (CamelStore *parent_store,
-                          const gchar *full_name,
-                          guint32 flags,
-                          GError **error)
-{
-	CamelFolder *folder;
-	gchar *basename;
-
-	d(printf("Creating maildir folder: %s\n", full_name));
-
-	if (g_strcmp0 (full_name, ".") == 0)
-		basename = g_strdup (_("Inbox"));
-	else
-		basename = g_path_get_basename (full_name);
-
-	folder = g_object_new (
-		CAMEL_TYPE_MAILDIR_FOLDER,
-		"name", basename, "full-name", full_name,
-		"parent-store", parent_store, NULL);
-
-	if (parent_store->flags & CAMEL_STORE_FILTER_INBOX
-	    && strcmp(full_name, ".") == 0)
-		folder->folder_flags |= CAMEL_FOLDER_FILTER_RECENT;
-
-	folder = (CamelFolder *) camel_local_folder_construct (
-		CAMEL_LOCAL_FOLDER (folder), flags, error);
-
-	g_free (basename);
-
-	return folder;
-}
-
-static CamelLocalSummary *
-maildir_create_summary (CamelLocalFolder *lf,
-                        const gchar *path,
-                        const gchar *folder,
-                        CamelIndex *index)
-{
-	return (CamelLocalSummary *) camel_maildir_summary_new (
-		CAMEL_FOLDER (lf), path, folder, index);
-}
-
 static gboolean
-maildir_append_message (CamelFolder *folder,
-                        CamelMimeMessage *message,
-                        const CamelMessageInfo *info,
-                        gchar **appended_uid,
-                        GError **error)
+maildir_folder_append_message (CamelFolder *folder,
+                               CamelMimeMessage *message,
+                               const CamelMessageInfo *info,
+                               gchar **appended_uid,
+                               GCancellable *cancellable,
+                               GError **error)
 {
 	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
 	CamelStream *output_stream;
@@ -160,8 +86,8 @@ maildir_append_message (CamelFolder *folder,
 		goto fail_write;
 
 	if (camel_data_wrapper_write_to_stream (
-		(CamelDataWrapper *)message, output_stream, error) == -1
-	    || camel_stream_close (output_stream, error) == -1)
+		(CamelDataWrapper *)message, output_stream, cancellable, error) == -1
+	    || camel_stream_close (output_stream, cancellable, error) == -1)
 		goto fail_write;
 
 	/* now move from tmp to cur (bypass new, does it matter?) */
@@ -216,38 +142,11 @@ maildir_append_message (CamelFolder *folder,
 	return success;
 }
 
-static gchar *
-maildir_get_filename (CamelFolder *folder,
-                      const gchar *uid,
-                      GError **error)
-{
-	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
-	CamelMaildirMessageInfo *mdi;
-	CamelMessageInfo *info;
-	gchar *res;
-
-	/* get the message summary info */
-	if ((info = camel_folder_summary_uid (folder->summary, uid)) == NULL) {
-		set_cannot_get_message_ex (
-			error, CAMEL_FOLDER_ERROR_INVALID_UID,
-			uid, lf->folder_path, _("No such message"));
-		return NULL;
-	}
-
-	mdi = (CamelMaildirMessageInfo *)info;
-
-	/* what do we do if the message flags (and :info data) changes?  filename mismatch - need to recheck I guess */
-	res = g_strdup_printf("%s/cur/%s", lf->folder_path, camel_maildir_info_filename (mdi));
-
-	camel_message_info_free (info);
-
-	return res;
-}
-
 static CamelMimeMessage *
-maildir_get_message (CamelFolder *folder,
-                     const gchar *uid,
-                     GError **error)
+maildir_folder_get_message (CamelFolder *folder,
+                            const gchar *uid,
+                            GCancellable *cancellable,
+                            GError **error)
 {
 	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
 	CamelStream *message_stream = NULL;
@@ -286,7 +185,7 @@ maildir_get_message (CamelFolder *folder,
 	}
 
 	message = camel_mime_message_new ();
-	if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)message, message_stream, error) == -1) {
+	if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)message, message_stream, cancellable, error) == -1) {
 		g_prefix_error (
 			error, _("Cannot get message %s from folder %s: "),
 			uid, lf->folder_path);
@@ -309,9 +208,9 @@ maildir_get_message (CamelFolder *folder,
 }
 
 static gint
-maildir_cmp_uids (CamelFolder *folder,
-                  const gchar *uid1,
-                  const gchar *uid2)
+maildir_folder_cmp_uids (CamelFolder *folder,
+                         const gchar *uid1,
+                         const gchar *uid2)
 {
 	CamelMessageInfo *a, *b;
 	time_t tma, tmb;
@@ -335,8 +234,8 @@ maildir_cmp_uids (CamelFolder *folder,
 }
 
 static void
-maildir_sort_uids (CamelFolder *folder,
-                   GPtrArray *uids)
+maildir_folder_sort_uids (CamelFolder *folder,
+                          GPtrArray *uids)
 {
 	g_return_if_fail (camel_maildir_folder_parent_class != NULL);
 	g_return_if_fail (folder != NULL);
@@ -349,12 +248,13 @@ maildir_sort_uids (CamelFolder *folder,
 }
 
 static gboolean
-maildir_transfer_messages_to (CamelFolder *source,
-                              GPtrArray *uids,
-                              CamelFolder *dest,
-                              GPtrArray **transferred_uids,
-                              gboolean delete_originals,
-                              GError **error)
+maildir_folder_transfer_messages_to (CamelFolder *source,
+                                     GPtrArray *uids,
+                                     CamelFolder *dest,
+                                     GPtrArray **transferred_uids,
+                                     gboolean delete_originals,
+                                     GCancellable *cancellable,
+                                     GError **error)
 {
 	gboolean fallback = FALSE;
 
@@ -363,7 +263,7 @@ maildir_transfer_messages_to (CamelFolder *source,
 		CamelLocalFolder *lf = (CamelLocalFolder *) source;
 		CamelLocalFolder *df = (CamelLocalFolder *) dest;
 
-		camel_operation_start(NULL, _("Moving messages"));
+		camel_operation_start (cancellable, _("Moving messages"));
 
 		camel_folder_freeze (dest);
 		camel_folder_freeze (source);
@@ -402,7 +302,9 @@ maildir_transfer_messages_to (CamelFolder *source,
 					break;
 				}
 			} else {
-				camel_folder_set_message_flags (source, uid, CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_SEEN, ~0);
+				camel_folder_set_message_flags (
+					source, uid, CAMEL_MESSAGE_DELETED |
+					CAMEL_MESSAGE_SEEN, ~0);
 				camel_folder_summary_remove (source->summary, info);
 			}
 
@@ -414,7 +316,7 @@ maildir_transfer_messages_to (CamelFolder *source,
 		camel_folder_thaw (source);
 		camel_folder_thaw (dest);
 
-		camel_operation_end (NULL);
+		camel_operation_end (cancellable);
 	} else
 		fallback = TRUE;
 
@@ -425,8 +327,104 @@ maildir_transfer_messages_to (CamelFolder *source,
 		folder_class = CAMEL_FOLDER_CLASS (camel_maildir_folder_parent_class);
 		return folder_class->transfer_messages_to (
 			source, uids, dest, transferred_uids,
-			delete_originals, error);
+			delete_originals, cancellable, error);
 	}
 
 	return TRUE;
 }
+
+static gchar *
+maildir_folder_get_filename (CamelFolder *folder,
+                             const gchar *uid,
+                             GError **error)
+{
+	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
+	CamelMaildirMessageInfo *mdi;
+	CamelMessageInfo *info;
+	gchar *res;
+
+	/* get the message summary info */
+	if ((info = camel_folder_summary_uid (folder->summary, uid)) == NULL) {
+		set_cannot_get_message_ex (
+			error, CAMEL_FOLDER_ERROR_INVALID_UID,
+			uid, lf->folder_path, _("No such message"));
+		return NULL;
+	}
+
+	mdi = (CamelMaildirMessageInfo *)info;
+
+	/* what do we do if the message flags (and :info data) changes?  filename mismatch - need to recheck I guess */
+	res = g_strdup_printf("%s/cur/%s", lf->folder_path, camel_maildir_info_filename (mdi));
+
+	camel_message_info_free (info);
+
+	return res;
+}
+
+static CamelLocalSummary *
+maildir_folder_create_summary (CamelLocalFolder *lf,
+                               const gchar *path,
+                               const gchar *folder,
+                               CamelIndex *index)
+{
+	return (CamelLocalSummary *) camel_maildir_summary_new (
+		CAMEL_FOLDER (lf), path, folder, index);
+}
+
+static void
+camel_maildir_folder_class_init (CamelMaildirFolderClass *class)
+{
+	CamelFolderClass *folder_class;
+	CamelLocalFolderClass *local_folder_class;
+
+	folder_class = CAMEL_FOLDER_CLASS (class);
+	folder_class->append_message = maildir_folder_append_message;
+	folder_class->get_message = maildir_folder_get_message;
+	folder_class->cmp_uids = maildir_folder_cmp_uids;
+	folder_class->sort_uids = maildir_folder_sort_uids;
+	folder_class->transfer_messages_to = maildir_folder_transfer_messages_to;
+	folder_class->get_filename = maildir_folder_get_filename;
+
+	local_folder_class = CAMEL_LOCAL_FOLDER_CLASS (class);
+	local_folder_class->create_summary = maildir_folder_create_summary;
+}
+
+static void
+camel_maildir_folder_init (CamelMaildirFolder *maildir_folder)
+{
+}
+
+CamelFolder *
+camel_maildir_folder_new (CamelStore *parent_store,
+                          const gchar *full_name,
+                          guint32 flags,
+                          GCancellable *cancellable,
+                          GError **error)
+{
+	CamelFolder *folder;
+	gchar *basename;
+
+	d(printf("Creating maildir folder: %s\n", full_name));
+
+	if (g_strcmp0 (full_name, ".") == 0)
+		basename = g_strdup (_("Inbox"));
+	else
+		basename = g_path_get_basename (full_name);
+
+	folder = g_object_new (
+		CAMEL_TYPE_MAILDIR_FOLDER,
+		"name", basename, "full-name", full_name,
+		"parent-store", parent_store, NULL);
+
+	if (parent_store->flags & CAMEL_STORE_FILTER_INBOX
+	    && strcmp(full_name, ".") == 0)
+		folder->folder_flags |= CAMEL_FOLDER_FILTER_RECENT;
+
+	folder = (CamelFolder *) camel_local_folder_construct (
+		CAMEL_LOCAL_FOLDER (folder), flags, cancellable, error);
+
+	g_free (basename);
+
+	return folder;
+}
+
diff --git a/camel/providers/local/camel-maildir-folder.h b/camel/providers/local/camel-maildir-folder.h
index 5f2915b..169537e 100644
--- a/camel/providers/local/camel-maildir-folder.h
+++ b/camel/providers/local/camel-maildir-folder.h
@@ -57,10 +57,12 @@ struct _CamelMaildirFolderClass {
 	CamelLocalFolderClass parent_class;
 };
 
-/* public methods */
-CamelFolder *camel_maildir_folder_new (CamelStore *parent_store, const gchar *full_name, guint32 flags, GError **error);
-
-GType camel_maildir_folder_get_type (void);
+GType		camel_maildir_folder_get_type	(void);
+CamelFolder *	camel_maildir_folder_new	(CamelStore *parent_store,
+						 const gchar *full_name,
+						 guint32 flags,
+						 GCancellable *cancellable,
+						 GError **error);
 
 G_END_DECLS
 
diff --git a/camel/providers/local/camel-maildir-store.c b/camel/providers/local/camel-maildir-store.c
index be8473e..0ced756 100644
--- a/camel/providers/local/camel-maildir-store.c
+++ b/camel/providers/local/camel-maildir-store.c
@@ -39,12 +39,12 @@
 
 #define d(x)
 
-static CamelFolder *get_folder (CamelStore * store, const gchar *folder_name, guint32 flags, GError **error);
-static CamelFolder *get_inbox (CamelStore *store, GError **error);
-static gboolean delete_folder (CamelStore * store, const gchar *folder_name, GError **error);
-static gboolean maildir_rename_folder (CamelStore *store, const gchar *old, const gchar *new, GError **error);
+static CamelFolder *get_folder (CamelStore * store, const gchar *folder_name, guint32 flags, GCancellable *cancellable, GError **error);
+static CamelFolder *get_inbox (CamelStore *store, GCancellable *cancellable, GError **error);
+static gboolean delete_folder (CamelStore * store, const gchar *folder_name, GCancellable *cancellable, GError **error);
+static gboolean maildir_rename_folder (CamelStore *store, const gchar *old, const gchar *new, GCancellable *cancellable, GError **error);
 
-static CamelFolderInfo * get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GError **error);
+static CamelFolderInfo * get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GCancellable *cancellable, GError **error);
 
 static gboolean maildir_compare_folder_name (gconstpointer a, gconstpointer b);
 static guint maildir_hash_folder_name (gconstpointer a);
@@ -103,6 +103,7 @@ static CamelFolder *
 get_folder (CamelStore *store,
             const gchar *folder_name,
             guint32 flags,
+            GCancellable *cancellable,
             GError **error)
 {
 	CamelStoreClass *store_class;
@@ -114,7 +115,7 @@ get_folder (CamelStore *store,
 
 	/* Chain up to parent's get_folder() method. */
 	store_class = CAMEL_STORE_CLASS (camel_maildir_store_parent_class);
-	if (!store_class->get_folder (store, folder_name, flags, error))
+	if (!store_class->get_folder (store, folder_name, flags, cancellable, error))
 		return NULL;
 
 	name = g_strdup_printf("%s%s", CAMEL_LOCAL_STORE(store)->toplevel_dir, folder_name);
@@ -141,7 +142,7 @@ get_folder (CamelStore *store,
 				goto fail;
 			}
 		}
-		folder = camel_maildir_folder_new (store, folder_name, flags, error);
+		folder = camel_maildir_folder_new (store, folder_name, flags, cancellable, error);
 	} else if (g_stat (name, &st) == -1) {
 		/* folder doesn't exist, see if we should create it */
 		if (errno != ENOENT) {
@@ -171,7 +172,7 @@ get_folder (CamelStore *store,
 				rmdir (new);
 				rmdir (name);
 			} else {
-				folder = camel_maildir_folder_new (store, folder_name, flags, error);
+				folder = camel_maildir_folder_new (store, folder_name, flags, cancellable, error);
 			}
 		}
 	} else if (!S_ISDIR (st.st_mode)
@@ -189,7 +190,7 @@ get_folder (CamelStore *store,
 			_("Cannot create folder '%s': folder exists."),
 			folder_name);
 	} else {
-		folder = camel_maildir_folder_new (store, folder_name, flags, error);
+		folder = camel_maildir_folder_new (store, folder_name, flags, cancellable, error);
 	}
 fail:
 	g_free (name);
@@ -202,15 +203,17 @@ fail:
 
 static CamelFolder *
 get_inbox (CamelStore *store,
+           GCancellable *cancellable,
            GError **error)
 {
 	return camel_store_get_folder (
-		store, ".", CAMEL_STORE_FOLDER_CREATE, error);
+		store, ".", CAMEL_STORE_FOLDER_CREATE, cancellable, error);
 }
 
 static gboolean
 delete_folder (CamelStore *store,
                const gchar *folder_name,
+               GCancellable *cancellable,
                GError **error)
 {
 	gchar *name, *tmp, *cur, *new;
@@ -287,7 +290,7 @@ delete_folder (CamelStore *store,
 			/* Chain up to parent's delete_folder() method. */
 			store_class = CAMEL_STORE_CLASS (camel_maildir_store_parent_class);
 			success = store_class->delete_folder (
-				store, folder_name, error);
+				store, folder_name, cancellable, error);
 		}
 	}
 
@@ -303,6 +306,7 @@ static gboolean
 maildir_rename_folder (CamelStore *store,
                        const gchar *old,
                        const gchar *new,
+                       GCancellable *cancellable,
                        GError **error)
 {
 	CamelStoreClass *store_class;
@@ -318,13 +322,14 @@ maildir_rename_folder (CamelStore *store,
 
 	/* Chain up to parent's rename_folder() method. */
 	store_class = CAMEL_STORE_CLASS (camel_maildir_store_parent_class);
-	return store_class->rename_folder (store, old, new, error);
+	return store_class->rename_folder (store, old, new, cancellable, error);
 }
 
 static void
 fill_fi (CamelStore *store,
          CamelFolderInfo *fi,
-         guint32 flags)
+         guint32 flags,
+         GCancellable *cancellable)
 {
 	CamelFolder *folder;
 
@@ -332,11 +337,11 @@ fill_fi (CamelStore *store,
 
 	if (folder == NULL
 	    && (flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0)
-		folder = camel_store_get_folder (store, fi->full_name, 0, NULL);
+		folder = camel_store_get_folder (store, fi->full_name, 0, cancellable, NULL);
 
 	if (folder) {
 		if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0)
-			camel_folder_refresh_info (folder, NULL);
+			camel_folder_refresh_info (folder, cancellable, NULL);
 		fi->unread = camel_folder_get_unread_message_count (folder);
 		fi->total = camel_folder_get_message_count (folder);
 		g_object_unref (folder);
@@ -397,7 +402,8 @@ scan_fi (CamelStore *store,
          guint32 flags,
          CamelURL *url,
          const gchar *full,
-         const gchar *name)
+         const gchar *name,
+         GCancellable *cancellable)
 {
 	CamelFolderInfo *fi;
 	gchar *tmp, *cur, *new;
@@ -431,7 +437,7 @@ scan_fi (CamelStore *store,
 	g_free (cur);
 	g_free (tmp);
 
-	fill_fi (store, fi, flags);
+	fill_fi (store, fi, flags, cancellable);
 
 	return fi;
 }
@@ -441,6 +447,7 @@ scan_dirs (CamelStore *store,
            guint32 flags,
            CamelFolderInfo *topfi,
            CamelURL *url,
+           GCancellable *cancellable,
            GError **error)
 {
 	CamelDList queue = CAMEL_DLIST_INITIALISER (queue);
@@ -512,7 +519,7 @@ scan_dirs (CamelStore *store,
 						full = g_strdup (d->d_name);
 					else
 						full = g_strdup_printf("%s/%s", sn->fi->full_name, d->d_name);
-					snew->fi = scan_fi (store, flags, url, full, d->d_name);
+					snew->fi = scan_fi (store, flags, url, full, d->d_name, cancellable);
 					g_free (full);
 
 					last->next =  snew->fi;
@@ -546,6 +553,7 @@ static CamelFolderInfo *
 get_folder_info (CamelStore *store,
                  const gchar *top,
                  guint32 flags,
+                 GCancellable *cancellable,
                  GError **error)
 {
 	CamelFolderInfo *fi = NULL;
@@ -559,8 +567,8 @@ get_folder_info (CamelStore *store,
 		CamelFolderInfo *scan;
 
 		/* create a dummy "." parent inbox, use to scan, then put back at the top level */
-		fi = scan_fi(store, flags, url, ".", _("Inbox"));
-		if (scan_dirs (store, flags, fi, url, error) == -1)
+		fi = scan_fi(store, flags, url, ".", _("Inbox"), cancellable);
+		if (scan_dirs (store, flags, fi, url, cancellable, error) == -1)
 			goto fail;
 		fi->next = fi->child;
 		scan = fi->child;
@@ -572,13 +580,13 @@ get_folder_info (CamelStore *store,
 		fi->flags &= ~CAMEL_FOLDER_CHILDREN;
 		fi->flags |= CAMEL_FOLDER_SYSTEM|CAMEL_FOLDER_NOCHILDREN|CAMEL_FOLDER_NOINFERIORS|CAMEL_FOLDER_TYPE_INBOX;
 	} else if (!strcmp(top, ".")) {
-		fi = scan_fi(store, flags, url, ".", _("Inbox"));
+		fi = scan_fi(store, flags, url, ".", _("Inbox"), cancellable);
 		fi->flags |= CAMEL_FOLDER_SYSTEM|CAMEL_FOLDER_NOCHILDREN|CAMEL_FOLDER_NOINFERIORS|CAMEL_FOLDER_TYPE_INBOX;
 	} else {
 		const gchar *name = strrchr (top, '/');
 
-		fi = scan_fi (store, flags, url, top, name?name+1:top);
-		if (scan_dirs (store, flags, fi, url, error) == -1)
+		fi = scan_fi (store, flags, url, top, name?name+1:top, cancellable);
+		if (scan_dirs (store, flags, fi, url, cancellable, error) == -1)
 			goto fail;
 	}
 
diff --git a/camel/providers/local/camel-maildir-summary.c b/camel/providers/local/camel-maildir-summary.c
index 61b8e4c..dca9bb8 100644
--- a/camel/providers/local/camel-maildir-summary.c
+++ b/camel/providers/local/camel-maildir-summary.c
@@ -51,8 +51,8 @@ static CamelMessageInfo *message_info_new_from_header (CamelFolderSummary *, str
 static void message_info_free (CamelFolderSummary *, CamelMessageInfo *mi);
 
 static gint maildir_summary_load (CamelLocalSummary *cls, gint forceindex, GError **error);
-static gint maildir_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GError **error);
-static gint maildir_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error);
+static gint maildir_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error);
+static gint maildir_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error);
 static CamelMessageInfo *maildir_summary_add (CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, GError **error);
 
 static gchar *maildir_summary_next_uid_string (CamelFolderSummary *s);
@@ -473,7 +473,10 @@ maildir_summary_load (CamelLocalSummary *cls,
 }
 
 static gint
-camel_maildir_summary_add (CamelLocalSummary *cls, const gchar *name, gint forceindex)
+camel_maildir_summary_add (CamelLocalSummary *cls,
+                           const gchar *name,
+                           gint forceindex,
+                           GCancellable *cancellable)
 {
 	CamelMaildirSummary *maildirs = (CamelMaildirSummary *)cls;
 	gchar *filename = g_strdup_printf("%s/cur/%s", cls->folder_path, name);
@@ -524,7 +527,10 @@ remove_summary (gchar *key, CamelMessageInfo *info, struct _remove_data *rd)
 }
 
 static gint
-maildir_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, GError **error)
+maildir_summary_check (CamelLocalSummary *cls,
+                       CamelFolderChangeInfo *changes,
+                       GCancellable *cancellable,
+                       GError **error)
 {
 	DIR *dir;
 	struct dirent *d;
@@ -546,7 +552,7 @@ maildir_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, G
 
 	d(printf("checking summary ...\n"));
 
-	camel_operation_start(NULL, _("Checking folder consistency"));
+	camel_operation_start (cancellable, _("Checking folder consistency"));
 
 	/* scan the directory, check for mail files not in the index, or index entries that
 	   no longer exist */
@@ -559,7 +565,7 @@ maildir_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, G
 			cls->folder_path, g_strerror (errno));
 		g_free (cur);
 		g_free (new);
-		camel_operation_end (NULL);
+		camel_operation_end (cancellable);
 		g_mutex_unlock (((CamelMaildirSummary *) cls)->priv->summary_lock);
 		return -1;
 	}
@@ -586,7 +592,7 @@ maildir_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, G
 	while ((d = readdir (dir))) {
 		gint pc = count * 100 / total;
 
-		camel_operation_progress (NULL, pc);
+		camel_operation_progress (cancellable, pc);
 		count++;
 
 		/* FIXME: also run stat to check for regular file */
@@ -610,7 +616,7 @@ maildir_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, G
 		info = camel_folder_summary_uid ((CamelFolderSummary *)cls, uid);
 		if (info == NULL) {
 			/* must be a message incorporated by another client, this is not a 'recent' uid */
-			if (camel_maildir_summary_add (cls, d->d_name, forceindex) == 0)
+			if (camel_maildir_summary_add (cls, d->d_name, forceindex, cancellable) == 0)
 				if (changes)
 					camel_folder_change_info_add_uid (changes, uid);
 		} else {
@@ -618,7 +624,7 @@ maildir_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, G
 
 			if (cls->index && (!camel_index_has_name (cls->index, uid))) {
 				/* message_info_new will handle duplicates */
-				camel_maildir_summary_add (cls, d->d_name, forceindex);
+				camel_maildir_summary_add (cls, d->d_name, forceindex, cancellable);
 			}
 
 			mdi = (CamelMaildirMessageInfo *)info;
@@ -636,9 +642,9 @@ maildir_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, G
 	g_hash_table_foreach (left, (GHFunc)remove_summary, &rd);
 	g_hash_table_destroy (left);
 
-	camel_operation_end (NULL);
+	camel_operation_end (cancellable);
 
-	camel_operation_start(NULL, _("Checking for new messages"));
+	camel_operation_start (cancellable, _("Checking for new messages"));
 
 	/* now, scan new for new messages, and copy them to cur, and so forth */
 	dir = opendir (new);
@@ -654,7 +660,7 @@ maildir_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, G
 			gchar *src, *dest;
 			gint pc = count * 100 / total;
 
-			camel_operation_progress (NULL, pc);
+			camel_operation_progress (cancellable, pc);
 			count++;
 
 			name = d->d_name;
@@ -682,7 +688,7 @@ maildir_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, G
 			/* FIXME: This should probably use link/unlink */
 
 			if (g_rename (src, dest) == 0) {
-				camel_maildir_summary_add (cls, destfilename, forceindex);
+				camel_maildir_summary_add (cls, destfilename, forceindex, cancellable);
 				if (changes) {
 					camel_folder_change_info_add_uid (changes, destname);
 					camel_folder_change_info_recent_uid (changes, destname);
@@ -698,7 +704,7 @@ maildir_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, G
 			g_free (src);
 			g_free (dest);
 		}
-		camel_operation_end (NULL);
+		camel_operation_end (cancellable);
 		closedir (dir);
 	}
 
@@ -715,6 +721,7 @@ static gint
 maildir_summary_sync (CamelLocalSummary *cls,
                       gboolean expunge,
                       CamelFolderChangeInfo *changes,
+                      GCancellable *cancellable,
                       GError **error)
 {
 	CamelLocalSummaryClass *local_summary_class;
@@ -726,15 +733,15 @@ maildir_summary_sync (CamelLocalSummary *cls,
 
 	d(printf("summary_sync(expunge=%s)\n", expunge?"true":"false"));
 
-	if (camel_local_summary_check (cls, changes, error) == -1)
+	if (camel_local_summary_check (cls, changes, cancellable, error) == -1)
 		return -1;
 
-	camel_operation_start(NULL, _("Storing folder"));
+	camel_operation_start (cancellable, _("Storing folder"));
 
 	camel_folder_summary_prepare_fetch_all ((CamelFolderSummary *)cls, error);
 	count = camel_folder_summary_count ((CamelFolderSummary *)cls);
 	for (i=count-1;i>=0;i--) {
-		camel_operation_progress (NULL, (count-i)*100/count);
+		camel_operation_progress (cancellable, (count-i)*100/count);
 
 		info = camel_folder_summary_index ((CamelFolderSummary *)cls, i);
 		mdi = (CamelMaildirMessageInfo *)info;
@@ -785,10 +792,10 @@ maildir_summary_sync (CamelLocalSummary *cls,
 		camel_message_info_free (info);
 	}
 
-	camel_operation_end (NULL);
+	camel_operation_end (cancellable);
 
 	/* Chain up to parent's sync() method. */
 	local_summary_class = CAMEL_LOCAL_SUMMARY_CLASS (camel_maildir_summary_parent_class);
-	return local_summary_class->sync (cls, expunge, changes, error);
+	return local_summary_class->sync (cls, expunge, changes, cancellable, error);
 }
 
diff --git a/camel/providers/local/camel-mbox-folder.c b/camel/providers/local/camel-mbox-folder.c
index 0db0e54..774ab7e 100644
--- a/camel/providers/local/camel-mbox-folder.c
+++ b/camel/providers/local/camel-mbox-folder.c
@@ -46,113 +46,15 @@
 
 #define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
 
-static gint mbox_lock (CamelLocalFolder *lf, CamelLockType type, GError **error);
-static void mbox_unlock (CamelLocalFolder *lf);
-
-static gboolean mbox_append_message (CamelFolder *folder, CamelMimeMessage * message, const CamelMessageInfo * info,	gchar **appended_uid, GError **error);
-static CamelMimeMessage *mbox_get_message (CamelFolder *folder, const gchar * uid, GError **error);
-static CamelLocalSummary *mbox_create_summary (CamelLocalFolder *lf, const gchar *path, const gchar *folder, CamelIndex *index);
-static gchar * mbox_get_filename (CamelFolder *folder, const gchar *uid, GError **error);
-static gint mbox_cmp_uids (CamelFolder *folder, const gchar *uid1, const gchar *uid2);
-static void mbox_sort_uids (CamelFolder *folder, GPtrArray *uids);
-
 G_DEFINE_TYPE (CamelMboxFolder, camel_mbox_folder, CAMEL_TYPE_LOCAL_FOLDER)
 
-static void
-camel_mbox_folder_class_init (CamelMboxFolderClass *class)
-{
-	CamelFolderClass *folder_class;
-	CamelLocalFolderClass *local_folder_class;
-
-	folder_class = CAMEL_FOLDER_CLASS (class);
-	folder_class->append_message = mbox_append_message;
-	folder_class->get_message = mbox_get_message;
-	folder_class->get_filename = mbox_get_filename;
-	folder_class->cmp_uids = mbox_cmp_uids;
-	folder_class->sort_uids = mbox_sort_uids;
-
-	local_folder_class = CAMEL_LOCAL_FOLDER_CLASS (class);
-	local_folder_class->create_summary = mbox_create_summary;
-	local_folder_class->lock = mbox_lock;
-	local_folder_class->unlock = mbox_unlock;
-}
-
-static void
-camel_mbox_folder_init (CamelMboxFolder *mbox_folder)
-{
-	mbox_folder->lockfd = -1;
-}
-
-CamelFolder *
-camel_mbox_folder_new (CamelStore *parent_store, const gchar *full_name, guint32 flags, GError **error)
-{
-	CamelFolder *folder;
-	gchar *basename;
-
-	basename = g_path_get_basename (full_name);
-
-	folder = g_object_new (
-		CAMEL_TYPE_MBOX_FOLDER,
-		"name", basename, "full-name", full_name,
-		"parent-store", parent_store, NULL);
-	folder = (CamelFolder *)camel_local_folder_construct (
-		(CamelLocalFolder *)folder, flags, error);
-
-	g_free (basename);
-
-	return folder;
-}
-
-static CamelLocalSummary *mbox_create_summary (CamelLocalFolder *lf, const gchar *path, const gchar *folder, CamelIndex *index)
-{
-	return (CamelLocalSummary *)camel_mbox_summary_new ((CamelFolder *)lf, path, folder, index);
-}
-
-static gint mbox_lock (CamelLocalFolder *lf, CamelLockType type, GError **error)
-{
-#ifndef G_OS_WIN32
-	CamelMboxFolder *mf = (CamelMboxFolder *)lf;
-
-	/* make sure we have matching unlocks for locks, camel-local-folder class should enforce this */
-	g_assert (mf->lockfd == -1);
-
-	mf->lockfd = open (lf->folder_path, O_RDWR|O_LARGEFILE, 0);
-	if (mf->lockfd == -1) {
-		g_set_error (
-			error, G_IO_ERROR,
-			g_io_error_from_errno (errno),
-			_("Cannot create folder lock on %s: %s"),
-			lf->folder_path, g_strerror (errno));
-		return -1;
-	}
-
-	if (camel_lock_folder (lf->folder_path, mf->lockfd, type, error) == -1) {
-		close (mf->lockfd);
-		mf->lockfd = -1;
-		return -1;
-	}
-#endif
-	return 0;
-}
-
-static void mbox_unlock (CamelLocalFolder *lf)
-{
-#ifndef G_OS_WIN32
-	CamelMboxFolder *mf = (CamelMboxFolder *)lf;
-
-	g_assert (mf->lockfd != -1);
-	camel_unlock_folder (lf->folder_path, mf->lockfd);
-	close (mf->lockfd);
-	mf->lockfd = -1;
-#endif
-}
-
 static gboolean
-mbox_append_message (CamelFolder *folder,
-                     CamelMimeMessage *message,
-                     const CamelMessageInfo *info,
-                     gchar **appended_uid,
-                     GError **error)
+mbox_folder_append_message (CamelFolder *folder,
+                            CamelMimeMessage *message,
+                            const CamelMessageInfo *info,
+                            gchar **appended_uid,
+                            GCancellable *cancellable,
+                            GError **error)
 {
 	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
 	CamelStream *output_stream = NULL, *filter_stream = NULL;
@@ -172,7 +74,7 @@ mbox_append_message (CamelFolder *folder,
 	d(printf("Appending message\n"));
 
 	/* first, check the summary is correct (updates folder_size too) */
-	retval = camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, error);
+	retval = camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, cancellable, error);
 	if (retval == -1)
 		goto fail;
 
@@ -210,7 +112,7 @@ mbox_append_message (CamelFolder *folder,
 
 	/* we must write this to the non-filtered stream ... */
 	fromline = camel_mime_message_build_mbox_from (message);
-	if (camel_stream_write (output_stream, fromline, strlen (fromline), error) == -1)
+	if (camel_stream_write (output_stream, fromline, strlen (fromline), cancellable, error) == -1)
 		goto fail_write;
 
 	/* and write the content to the filtering stream, that translates '\nFrom' into '\n>From' */
@@ -220,9 +122,9 @@ mbox_append_message (CamelFolder *folder,
 	g_object_unref (filter_from);
 
 	if (camel_data_wrapper_write_to_stream (
-		(CamelDataWrapper *) message, filter_stream, error) == -1 ||
-	    camel_stream_write (filter_stream, "\n", 1, error) == -1 ||
-	    camel_stream_flush (filter_stream, error) == -1)
+		(CamelDataWrapper *) message, filter_stream, cancellable, error) == -1 ||
+	    camel_stream_write (filter_stream, "\n", 1, cancellable, error) == -1 ||
+	    camel_stream_flush (filter_stream, cancellable, error) == -1)
 		goto fail_write;
 
 	/* filter stream ref's the output stream itself, so we need to unref it too */
@@ -300,55 +202,11 @@ fail:
 	return FALSE;
 }
 
-static gchar *
-mbox_get_filename (CamelFolder *folder, const gchar *uid, GError **error)
-{
-	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
-	CamelMboxMessageInfo *info;
-	goffset frompos;
-	gchar *filename = NULL;
-
-	d(printf("Getting message %s\n", uid));
-
-	/* lock the folder first, burn if we can't, need write lock for summary check */
-	if (camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1)
-		return NULL;
-
-	/* check for new messages always */
-	if (camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, error) == -1) {
-		camel_local_folder_unlock (lf);
-		return NULL;
-	}
-
-	/* get the message summary info */
-	info = (CamelMboxMessageInfo *) camel_folder_summary_uid (folder->summary, uid);
-
-	if (info == NULL) {
-		set_cannot_get_message_ex (
-			error, CAMEL_FOLDER_ERROR_INVALID_UID,
-			uid, lf->folder_path, _("No such message"));
-		goto fail;
-	}
-
-	if (info->frompos == -1) {
-		camel_message_info_free ((CamelMessageInfo *)info);
-		goto fail;
-	}
-
-	frompos = info->frompos;
-	camel_message_info_free ((CamelMessageInfo *)info);
-
-	filename = g_strdup_printf ("%s%s!%" PRId64, lf->folder_path, G_DIR_SEPARATOR_S, (gint64) frompos);
-
-fail:
-	/* and unlock now we're finished with it */
-	camel_local_folder_unlock (lf);
-
-	return filename;
-}
-
 static CamelMimeMessage *
-mbox_get_message (CamelFolder *folder, const gchar * uid, GError **error)
+mbox_folder_get_message (CamelFolder *folder,
+                         const gchar *uid,
+                         GCancellable *cancellable,
+                         GError **error)
 {
 	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
 	CamelMimeMessage *message = NULL;
@@ -365,7 +223,7 @@ mbox_get_message (CamelFolder *folder, const gchar * uid, GError **error)
 		return NULL;
 
 	/* check for new messages always */
-	if (camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, error) == -1) {
+	if (camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, cancellable, error) == -1) {
 		camel_local_folder_unlock (lf);
 		return NULL;
 	}
@@ -422,7 +280,7 @@ retry:
 		if (!retried) {
 			retried = TRUE;
 			camel_local_summary_check_force ((CamelLocalSummary *)folder->summary);
-			retval = camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, error);
+			retval = camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, cancellable, error);
 			if (retval != -1)
 				goto retry;
 		}
@@ -435,7 +293,7 @@ retry:
 	}
 
 	message = camel_mime_message_new ();
-	if (camel_mime_part_construct_from_parser ((CamelMimePart *)message, parser, error) == -1) {
+	if (camel_mime_part_construct_from_parser ((CamelMimePart *)message, parser, cancellable, error) == -1) {
 		g_prefix_error (
 			error, _("Cannot get message %s from folder %s: "),
 			uid, lf->folder_path);
@@ -463,7 +321,9 @@ fail:
 }
 
 static gint
-mbox_cmp_uids (CamelFolder *folder, const gchar *uid1, const gchar *uid2)
+mbox_folder_cmp_uids (CamelFolder *folder,
+                      const gchar *uid1,
+                      const gchar *uid2)
 {
 	CamelMboxMessageInfo *a, *b;
 	gint res;
@@ -486,7 +346,8 @@ mbox_cmp_uids (CamelFolder *folder, const gchar *uid1, const gchar *uid2)
 }
 
 static void
-mbox_sort_uids (CamelFolder *folder, GPtrArray *uids)
+mbox_folder_sort_uids (CamelFolder *folder,
+                       GPtrArray *uids)
 {
 	g_return_if_fail (camel_mbox_folder_parent_class != NULL);
 	g_return_if_fail (folder != NULL);
@@ -496,3 +357,154 @@ mbox_sort_uids (CamelFolder *folder, GPtrArray *uids)
 
 	CAMEL_FOLDER_CLASS (camel_mbox_folder_parent_class)->sort_uids (folder, uids);
 }
+
+static gchar *
+mbox_folder_get_filename (CamelFolder *folder,
+                          const gchar *uid,
+                          GError **error)
+{
+	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
+	CamelMboxMessageInfo *info;
+	goffset frompos;
+	gchar *filename = NULL;
+
+	d(printf("Getting message %s\n", uid));
+
+	/* lock the folder first, burn if we can't, need write lock for summary check */
+	if (camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1)
+		return NULL;
+
+	/* check for new messages always */
+	if (camel_local_summary_check ((CamelLocalSummary *)folder->summary, lf->changes, NULL, error) == -1) {
+		camel_local_folder_unlock (lf);
+		return NULL;
+	}
+
+	/* get the message summary info */
+	info = (CamelMboxMessageInfo *) camel_folder_summary_uid (folder->summary, uid);
+
+	if (info == NULL) {
+		set_cannot_get_message_ex (
+			error, CAMEL_FOLDER_ERROR_INVALID_UID,
+			uid, lf->folder_path, _("No such message"));
+		goto fail;
+	}
+
+	if (info->frompos == -1) {
+		camel_message_info_free ((CamelMessageInfo *)info);
+		goto fail;
+	}
+
+	frompos = info->frompos;
+	camel_message_info_free ((CamelMessageInfo *)info);
+
+	filename = g_strdup_printf ("%s%s!%" PRId64, lf->folder_path, G_DIR_SEPARATOR_S, (gint64) frompos);
+
+fail:
+	/* and unlock now we're finished with it */
+	camel_local_folder_unlock (lf);
+
+	return filename;
+}
+
+static CamelLocalSummary *
+mbox_folder_create_summary (CamelLocalFolder *lf,
+                            const gchar *path,
+                            const gchar *folder,
+                            CamelIndex *index)
+{
+	return (CamelLocalSummary *)camel_mbox_summary_new ((CamelFolder *)lf, path, folder, index);
+}
+
+static gint
+mbox_folder_lock (CamelLocalFolder *lf,
+                  CamelLockType type,
+                  GError **error)
+{
+#ifndef G_OS_WIN32
+	CamelMboxFolder *mf = (CamelMboxFolder *)lf;
+
+	/* make sure we have matching unlocks for locks, camel-local-folder class should enforce this */
+	g_assert (mf->lockfd == -1);
+
+	mf->lockfd = open (lf->folder_path, O_RDWR|O_LARGEFILE, 0);
+	if (mf->lockfd == -1) {
+		g_set_error (
+			error, G_IO_ERROR,
+			g_io_error_from_errno (errno),
+			_("Cannot create folder lock on %s: %s"),
+			lf->folder_path, g_strerror (errno));
+		return -1;
+	}
+
+	if (camel_lock_folder (lf->folder_path, mf->lockfd, type, error) == -1) {
+		close (mf->lockfd);
+		mf->lockfd = -1;
+		return -1;
+	}
+#endif
+	return 0;
+}
+
+static void
+mbox_folder_unlock (CamelLocalFolder *lf)
+{
+#ifndef G_OS_WIN32
+	CamelMboxFolder *mf = (CamelMboxFolder *)lf;
+
+	g_assert (mf->lockfd != -1);
+	camel_unlock_folder (lf->folder_path, mf->lockfd);
+	close (mf->lockfd);
+	mf->lockfd = -1;
+#endif
+}
+
+static void
+camel_mbox_folder_class_init (CamelMboxFolderClass *class)
+{
+	CamelFolderClass *folder_class;
+	CamelLocalFolderClass *local_folder_class;
+
+	folder_class = CAMEL_FOLDER_CLASS (class);
+	folder_class->append_message = mbox_folder_append_message;
+	folder_class->get_message = mbox_folder_get_message;
+	folder_class->cmp_uids = mbox_folder_cmp_uids;
+	folder_class->sort_uids = mbox_folder_sort_uids;
+	folder_class->get_filename = mbox_folder_get_filename;
+
+	local_folder_class = CAMEL_LOCAL_FOLDER_CLASS (class);
+	local_folder_class->create_summary = mbox_folder_create_summary;
+	local_folder_class->lock = mbox_folder_lock;
+	local_folder_class->unlock = mbox_folder_unlock;
+}
+
+static void
+camel_mbox_folder_init (CamelMboxFolder *mbox_folder)
+{
+	mbox_folder->lockfd = -1;
+}
+
+CamelFolder *
+camel_mbox_folder_new (CamelStore *parent_store,
+                       const gchar *full_name,
+                       guint32 flags,
+                       GCancellable *cancellable,
+                       GError **error)
+{
+	CamelFolder *folder;
+	gchar *basename;
+
+	basename = g_path_get_basename (full_name);
+
+	folder = g_object_new (
+		CAMEL_TYPE_MBOX_FOLDER,
+		"name", basename, "full-name", full_name,
+		"parent-store", parent_store, NULL);
+	folder = (CamelFolder *)camel_local_folder_construct (
+		(CamelLocalFolder *)folder, flags, cancellable, error);
+
+	g_free (basename);
+
+	return folder;
+}
+
diff --git a/camel/providers/local/camel-mbox-folder.h b/camel/providers/local/camel-mbox-folder.h
index b3379bb..90500b5 100644
--- a/camel/providers/local/camel-mbox-folder.h
+++ b/camel/providers/local/camel-mbox-folder.h
@@ -59,11 +59,12 @@ struct _CamelMboxFolderClass {
 	CamelLocalFolderClass parent_class;
 };
 
-/* public methods */
-/* flags are taken from CAMEL_STORE_FOLDER_* flags */
-CamelFolder *camel_mbox_folder_new (CamelStore *parent_store, const gchar *full_name, guint32 flags, GError **error);
-
-GType camel_mbox_folder_get_type (void);
+GType		camel_mbox_folder_get_type	(void);
+CamelFolder *	camel_mbox_folder_new		(CamelStore *parent_store,
+						 const gchar *full_name,
+						 guint32 flags,
+						 GCancellable *cancellable,
+						 GError **error);
 
 G_END_DECLS
 
diff --git a/camel/providers/local/camel-mbox-store.c b/camel/providers/local/camel-mbox-store.c
index 22f3247..9830155 100644
--- a/camel/providers/local/camel-mbox-store.c
+++ b/camel/providers/local/camel-mbox-store.c
@@ -38,11 +38,11 @@
 
 #define d(x)
 
-static CamelFolder *get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError **error);
-static gboolean delete_folder (CamelStore *store, const gchar *folder_name, GError **error);
-static gboolean rename_folder (CamelStore *store, const gchar *old, const gchar *new, GError **error);
-static CamelFolderInfo *create_folder (CamelStore *store, const gchar *parent_name, const gchar *folder_name, GError **error);
-static CamelFolderInfo *get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GError **error);
+static CamelFolder *get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GCancellable *cancellable, GError **error);
+static gboolean delete_folder (CamelStore *store, const gchar *folder_name, GCancellable *cancellable, GError **error);
+static gboolean rename_folder (CamelStore *store, const gchar *old, const gchar *new, GCancellable *cancellable, GError **error);
+static CamelFolderInfo *create_folder (CamelStore *store, const gchar *parent_name, const gchar *folder_name, GCancellable *cancellable, GError **error);
+static CamelFolderInfo *get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GCancellable *cancellable, GError **error);
 static gchar *mbox_get_meta_path (CamelLocalStore *ls, const gchar *full_name, const gchar *ext);
 static gchar *mbox_get_full_path (CamelLocalStore *ls, const gchar *full_name);
 
@@ -102,6 +102,7 @@ static CamelFolder *
 get_folder (CamelStore *store,
             const gchar *folder_name,
             guint32 flags,
+            GCancellable *cancellable,
             GError **error)
 {
 	CamelStoreClass *store_class;
@@ -110,7 +111,7 @@ get_folder (CamelStore *store,
 
 	/* Chain up to parent's get_folder() method. */
 	store_class = CAMEL_STORE_CLASS (camel_mbox_store_parent_class);
-	if (!store_class->get_folder (store, folder_name, flags, error))
+	if (!store_class->get_folder (store, folder_name, flags, cancellable, error))
 		return NULL;
 
 	name = camel_local_store_get_full_path (store, folder_name);
@@ -197,11 +198,14 @@ get_folder (CamelStore *store,
 	} else
 		g_free (name);
 
-	return camel_mbox_folder_new (store, folder_name, flags, error);
+	return camel_mbox_folder_new (store, folder_name, flags, cancellable, error);
 }
 
 static gboolean
-delete_folder (CamelStore *store, const gchar *folder_name, GError **error)
+delete_folder (CamelStore *store,
+               const gchar *folder_name,
+               GCancellable *cancellable,
+               GError **error)
 {
 	CamelFolderInfo *fi;
 	CamelFolder *lf;
@@ -311,7 +315,7 @@ delete_folder (CamelStore *store, const gchar *folder_name, GError **error)
 	g_free (path);
 
 	path = NULL;
-	if ((lf = camel_store_get_folder (store, folder_name, 0, NULL))) {
+	if ((lf = camel_store_get_folder (store, folder_name, 0, cancellable, NULL))) {
 		CamelObject *object = CAMEL_OBJECT (lf);
 		const gchar *state_filename;
 
@@ -354,7 +358,11 @@ delete_folder (CamelStore *store, const gchar *folder_name, GError **error)
 }
 
 static CamelFolderInfo *
-create_folder (CamelStore *store, const gchar *parent_name, const gchar *folder_name, GError **error)
+create_folder (CamelStore *store,
+               const gchar *parent_name,
+               const gchar *folder_name,
+               GCancellable *cancellable,
+               GError **error)
 {
 	/* FIXME: this is almost an exact copy of CamelLocalStore::create_folder() except that we use
 	 * different path schemes... need to find a way to share parent's code? */
@@ -421,11 +429,11 @@ create_folder (CamelStore *store, const gchar *parent_name, const gchar *folder_
 	g_free (path);
 
 	folder = CAMEL_STORE_GET_CLASS (store)->get_folder (
-		store, name, CAMEL_STORE_FOLDER_CREATE, error);
+		store, name, CAMEL_STORE_FOLDER_CREATE, cancellable, error);
 	if (folder) {
 		g_object_unref (folder);
 		info = CAMEL_STORE_GET_CLASS (store)->get_folder_info (
-			store, name, 0, error);
+			store, name, 0, cancellable, error);
 	}
 
 	g_free (name);
@@ -495,7 +503,11 @@ xrename (CamelStore *store, const gchar *old_name, const gchar *new_name, const
 }
 
 static gboolean
-rename_folder (CamelStore *store, const gchar *old, const gchar *new, GError **error)
+rename_folder (CamelStore *store,
+               const gchar *old,
+               const gchar *new,
+               GCancellable *cancellable,
+               GError **error)
 {
 	CamelLocalFolder *folder = NULL;
 	gchar *oldibex, *newibex, *newdir;
@@ -644,7 +656,9 @@ inode_free (gpointer k, gpointer v, gpointer d)
 
 /* NB: duplicated in maildir store */
 static void
-fill_fi (CamelStore *store, CamelFolderInfo *fi, guint32 flags)
+fill_fi (CamelStore *store,
+         CamelFolderInfo *fi,
+         guint32 flags)
 {
 	CamelFolder *folder;
 
@@ -653,7 +667,7 @@ fill_fi (CamelStore *store, CamelFolderInfo *fi, guint32 flags)
 	folder = camel_object_bag_get (store->folders, fi->full_name);
 	if (folder) {
 		if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0)
-			camel_folder_refresh_info (folder, NULL);
+			camel_folder_refresh_info (folder, NULL, NULL);
 		fi->unread = camel_folder_get_unread_message_count (folder);
 		fi->total = camel_folder_get_message_count (folder);
 		g_object_unref (folder);
@@ -798,7 +812,11 @@ scan_dir (CamelStore *store, CamelURL *url, GHashTable *visited, CamelFolderInfo
 }
 
 static CamelFolderInfo *
-get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GError **error)
+get_folder_info (CamelStore *store,
+                 const gchar *top,
+                 guint32 flags,
+                 GCancellable *cancellable,
+                 GError **error)
 {
 	GHashTable *visited;
 #ifndef G_OS_WIN32
diff --git a/camel/providers/local/camel-mbox-summary.c b/camel/providers/local/camel-mbox-summary.c
index c0e3f38..86d0562 100644
--- a/camel/providers/local/camel-mbox-summary.c
+++ b/camel/providers/local/camel-mbox-summary.c
@@ -61,14 +61,14 @@ static CamelMessageInfo * message_info_migrate (CamelFolderSummary *, FILE *);
 
 static gchar *mbox_summary_encode_x_evolution (CamelLocalSummary *cls, const CamelLocalMessageInfo *mi);
 
-static gint mbox_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GError **error);
-static gint mbox_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error);
+static gint mbox_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error);
+static gint mbox_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error);
 #ifdef STATUS_PINE
 static CamelMessageInfo *mbox_summary_add (CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *ci, GError **error);
 #endif
 
-static gint mbox_summary_sync_quick (CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error);
-static gint mbox_summary_sync_full (CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error);
+static gint mbox_summary_sync_quick (CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error);
+static gint mbox_summary_sync_full (CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error);
 
 #ifdef STATUS_PINE
 /* Which status flags are stored in each separate header */
@@ -107,7 +107,9 @@ mbox_info_set_user_tag (CamelMessageInfo *mi, const gchar *name, const gchar *va
 
 #ifdef STATUS_PINE
 static gboolean
-mbox_info_set_flags (CamelMessageInfo *mi, guint32 flags, guint32 set)
+mbox_info_set_flags (CamelMessageInfo *mi,
+                     guint32 flags,
+                     guint32 set)
 {
 	/* Basically, if anything could change the Status line, presume it does */
 	if (((CamelMboxSummary *)mi->summary)->xstatus
@@ -116,7 +118,8 @@ mbox_info_set_flags (CamelMessageInfo *mi, guint32 flags, guint32 set)
 		set |= CAMEL_MESSAGE_FOLDER_XEVCHANGE|CAMEL_MESSAGE_FOLDER_FLAGGED;
 	}
 
-	return CAMEL_FOLDER_SUMMARY_CLASS (camel_mbox_summary_parent_class)->info_set_flags (mi, flags, set);
+	return CAMEL_FOLDER_SUMMARY_CLASS (camel_mbox_summary_parent_class)->
+		info_set_flags (mi, flags, set);
 }
 #endif
 
@@ -443,7 +446,11 @@ message_info_to_db (CamelFolderSummary *s, CamelMessageInfo *info)
 
 /* like summary_rebuild, but also do changeinfo stuff (if supplied) */
 static gint
-summary_update (CamelLocalSummary *cls, goffset offset, CamelFolderChangeInfo *changeinfo, GError **error)
+summary_update (CamelLocalSummary *cls,
+                goffset offset,
+                CamelFolderChangeInfo *changeinfo,
+                GCancellable *cancellable,
+                GError **error)
 {
 	gint i, count;
 	CamelFolderSummary *s = (CamelFolderSummary *)cls;
@@ -462,7 +469,7 @@ summary_update (CamelLocalSummary *cls, goffset offset, CamelFolderChangeInfo *c
 
 	cls->index_force = FALSE;
 
-	camel_operation_start(NULL, _("Storing folder"));
+	camel_operation_start (cancellable, _("Storing folder"));
 
 	fd = g_open (cls->folder_path, O_LARGEFILE | O_RDONLY | O_BINARY, 0);
 	if (fd == -1) {
@@ -472,7 +479,7 @@ summary_update (CamelLocalSummary *cls, goffset offset, CamelFolderChangeInfo *c
 			g_io_error_from_errno (errno),
 			_("Could not open folder: %s: %s"),
 			cls->folder_path, g_strerror (errno));
-		camel_operation_end (NULL);
+		camel_operation_end (cancellable);
 		return -1;
 	}
 
@@ -515,7 +522,8 @@ summary_update (CamelLocalSummary *cls, goffset offset, CamelFolderChangeInfo *c
 		CamelMessageInfo *info;
 		goffset pc = camel_mime_parser_tell_start_from (mp) + 1;
 
-		camel_operation_progress (NULL, (gint) (((gfloat) pc / size) * 100));
+		camel_operation_progress (
+			cancellable, (gint) (((gfloat) pc / size) * 100));
 
 		info = camel_folder_summary_add_from_parser (s, mp);
 		if (info == NULL) {
@@ -590,13 +598,16 @@ summary_update (CamelLocalSummary *cls, goffset offset, CamelFolderChangeInfo *c
 		}
 	}
 
-	camel_operation_end (NULL);
+	camel_operation_end (cancellable);
 
 	return ok;
 }
 
 static gint
-mbox_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, GError **error)
+mbox_summary_check (CamelLocalSummary *cls,
+                    CamelFolderChangeInfo *changes,
+                    GCancellable *cancellable,
+                    GError **error)
 {
 	CamelMboxSummary *mbs = (CamelMboxSummary *)cls;
 	CamelFolderSummary *s = (CamelFolderSummary *)cls;
@@ -642,10 +653,10 @@ mbox_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, GErr
 			if (mbs->folder_size < st.st_size) {
 				/* this will automatically rescan from 0 if there is a problem */
 				d(printf("folder grew, attempting to rebuild from %d\n", mbs->folder_size));
-				ret = summary_update (cls, mbs->folder_size, changes, error);
+				ret = summary_update (cls, mbs->folder_size, changes, cancellable, error);
 			} else {
 				d(printf("folder shrank!  rebuilding from start\n"));
-				 ret = summary_update (cls, 0, changes, error);
+				 ret = summary_update (cls, 0, changes, cancellable, error);
 			}
 		} else {
 			d(printf("Folder unchanged, do nothing\n"));
@@ -667,7 +678,11 @@ mbox_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changes, GErr
 
 /* perform a full sync */
 static gint
-mbox_summary_sync_full (CamelMboxSummary *mbs, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error)
+mbox_summary_sync_full (CamelMboxSummary *mbs,
+                        gboolean expunge,
+                        CamelFolderChangeInfo *changeinfo,
+                        GCancellable *cancellable,
+                        GError **error)
 {
 	CamelLocalSummary *cls = (CamelLocalSummary *)mbs;
 	gint fd = -1, fdout = -1;
@@ -676,7 +691,7 @@ mbox_summary_sync_full (CamelMboxSummary *mbs, gboolean expunge, CamelFolderChan
 
 	d(printf("performing full summary/sync\n"));
 
-	camel_operation_start(NULL, _("Storing folder"));
+	camel_operation_start (cancellable, _("Storing folder"));
 
 	fd = g_open (cls->folder_path, O_LARGEFILE | O_RDONLY | O_BINARY, 0);
 	if (fd == -1) {
@@ -685,7 +700,7 @@ mbox_summary_sync_full (CamelMboxSummary *mbs, gboolean expunge, CamelFolderChan
 			g_io_error_from_errno (errno),
 			_("Could not open file: %s: %s"),
 			cls->folder_path, g_strerror (errno));
-		camel_operation_end (NULL);
+		camel_operation_end (cancellable);
 		return -1;
 	}
 
@@ -702,7 +717,9 @@ mbox_summary_sync_full (CamelMboxSummary *mbs, gboolean expunge, CamelFolderChan
 		goto error;
 	}
 
-	if (camel_mbox_summary_sync_mbox ((CamelMboxSummary *)cls, flags, changeinfo, fd, fdout, error) == -1)
+	if (camel_mbox_summary_sync_mbox (
+		(CamelMboxSummary *)cls, flags, changeinfo,
+		fd, fdout, cancellable, error) == -1)
 		goto error;
 
 	d(printf("Closing folders\n"));
@@ -746,7 +763,7 @@ mbox_summary_sync_full (CamelMboxSummary *mbs, gboolean expunge, CamelFolderChan
 	}
 	tmpname = NULL;
 
-	camel_operation_end (NULL);
+	camel_operation_end (cancellable);
 
 	return 0;
  error:
@@ -759,7 +776,7 @@ mbox_summary_sync_full (CamelMboxSummary *mbs, gboolean expunge, CamelFolderChan
 	if (tmpname)
 		g_unlink (tmpname);
 
-	camel_operation_end (NULL);
+	camel_operation_end (cancellable);
 
 	return -1;
 }
@@ -790,7 +807,11 @@ cms_sort_frompos (gpointer a, gpointer b, gpointer data)
 
 /* perform a quick sync - only system flags have changed */
 static gint
-mbox_summary_sync_quick (CamelMboxSummary *mbs, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error)
+mbox_summary_sync_quick (CamelMboxSummary *mbs,
+                         gboolean expunge,
+                         CamelFolderChangeInfo *changeinfo,
+                         GCancellable *cancellable,
+                         GError **error)
 {
 	CamelLocalSummary *cls = (CamelLocalSummary *)mbs;
 	CamelFolderSummary *s = (CamelFolderSummary *)mbs;
@@ -806,7 +827,7 @@ mbox_summary_sync_quick (CamelMboxSummary *mbs, gboolean expunge, CamelFolderCha
 
 	d(printf("Performing quick summary sync\n"));
 
-	camel_operation_start(NULL, _("Storing folder"));
+	camel_operation_start (cancellable, _("Storing folder"));
 
 	fd = g_open (cls->folder_path, O_LARGEFILE|O_RDWR|O_BINARY, 0);
 	if (fd == -1) {
@@ -816,7 +837,7 @@ mbox_summary_sync_quick (CamelMboxSummary *mbs, gboolean expunge, CamelFolderCha
 			_("Could not open file: %s: %s"),
 			cls->folder_path, g_strerror (errno));
 
-		camel_operation_end (NULL);
+		camel_operation_end (cancellable);
 		return -1;
 	}
 
@@ -847,7 +868,7 @@ mbox_summary_sync_quick (CamelMboxSummary *mbs, gboolean expunge, CamelFolderCha
 		gint xevoffset;
 		gint pc = (i+1)*100/summary->len;
 
-		camel_operation_progress (NULL, pc);
+		camel_operation_progress (cancellable, pc);
 
 		info = (CamelMboxMessageInfo *)camel_folder_summary_uid (s, summary->pdata[i]);
 
@@ -939,7 +960,7 @@ mbox_summary_sync_quick (CamelMboxSummary *mbs, gboolean expunge, CamelFolderCha
 	g_ptr_array_free (summary, TRUE);
 	g_object_unref (mp);
 
-	camel_operation_end (NULL);
+	camel_operation_end (cancellable);
 	camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
 	return 0;
@@ -953,14 +974,18 @@ mbox_summary_sync_quick (CamelMboxSummary *mbs, gboolean expunge, CamelFolderCha
 	if (info)
 		camel_message_info_free ((CamelMessageInfo *)info);
 
-	camel_operation_end (NULL);
+	camel_operation_end (cancellable);
 	camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
 	return -1;
 }
 
 static gint
-mbox_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error)
+mbox_summary_sync (CamelLocalSummary *cls,
+                   gboolean expunge,
+                   CamelFolderChangeInfo *changeinfo,
+                   GCancellable *cancellable,
+                   GError **error)
 {
 	struct stat st;
 	CamelMboxSummary *mbs = (CamelMboxSummary *)cls;
@@ -973,7 +998,7 @@ mbox_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeIn
 	GPtrArray *summary = NULL;
 
 	/* first, sync ourselves up, just to make sure */
-	if (camel_local_summary_check (cls, changeinfo, error) == -1)
+	if (camel_local_summary_check (cls, changeinfo, cancellable, error) == -1)
 		return -1;
 
 	full_name = camel_folder_get_full_name (s->folder);
@@ -1009,7 +1034,8 @@ mbox_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeIn
 	ret = -1;
 	if (quick) {
 		if (work) {
-			ret = CAMEL_MBOX_SUMMARY_GET_CLASS (cls)->sync_quick (mbs, expunge, changeinfo, NULL);
+			ret = CAMEL_MBOX_SUMMARY_GET_CLASS (cls)->sync_quick (
+				mbs, expunge, changeinfo, cancellable, NULL);
 			if (ret == -1)
 				g_warning("failed a quick-sync, trying a full sync");
 		} else {
@@ -1018,7 +1044,8 @@ mbox_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeIn
 	}
 
 	if (ret == -1)
-		ret = CAMEL_MBOX_SUMMARY_GET_CLASS (cls)->sync_full (mbs, expunge, changeinfo, error);
+		ret = CAMEL_MBOX_SUMMARY_GET_CLASS (cls)->sync_full (
+			mbs, expunge, changeinfo, cancellable, error);
 	if (ret == -1)
 		return -1;
 
@@ -1036,11 +1063,17 @@ mbox_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeIn
 		camel_folder_summary_touch (s);
 	}
 
-	return CAMEL_LOCAL_SUMMARY_CLASS (camel_mbox_summary_parent_class)->sync (cls, expunge, changeinfo, error);
+	return CAMEL_LOCAL_SUMMARY_CLASS (camel_mbox_summary_parent_class)->sync (cls, expunge, changeinfo, cancellable, error);
 }
 
 gint
-camel_mbox_summary_sync_mbox (CamelMboxSummary *cls, guint32 flags, CamelFolderChangeInfo *changeinfo, gint fd, gint fdout, GError **error)
+camel_mbox_summary_sync_mbox (CamelMboxSummary *cls,
+                              guint32 flags,
+                              CamelFolderChangeInfo *changeinfo,
+                              gint fd,
+                              gint fdout,
+                              GCancellable *cancellable,
+                              GError **error)
 {
 	CamelMboxSummary *mbs = (CamelMboxSummary *)cls;
 	CamelFolderSummary *s = (CamelFolderSummary *)mbs;
@@ -1083,7 +1116,7 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls, guint32 flags, CamelFolderC
 	for (i = 0; i < count; i++) {
 		gint pc = (i + 1) * 100 / count;
 
-		camel_operation_progress (NULL, pc);
+		camel_operation_progress (cancellable, pc);
 
 		info = (CamelMboxMessageInfo *)camel_folder_summary_index (s, i);
 
@@ -1272,7 +1305,11 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls, guint32 flags, CamelFolderC
 
 #ifdef STATUS_PINE
 static CamelMessageInfo *
-mbox_summary_add (CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *ci, GError **error)
+mbox_summary_add (CamelLocalSummary *cls,
+                  CamelMimeMessage *msg,
+                  const CamelMessageInfo *info,
+                  CamelFolderChangeInfo *ci,
+                  GError **error)
 {
 	CamelLocalSummaryClass *local_summary_class;
 	CamelMboxMessageInfo *mi;
diff --git a/camel/providers/local/camel-mbox-summary.h b/camel/providers/local/camel-mbox-summary.h
index 1bf8d1d..b6409fd 100644
--- a/camel/providers/local/camel-mbox-summary.h
+++ b/camel/providers/local/camel-mbox-summary.h
@@ -75,19 +75,39 @@ struct _CamelMboxSummaryClass {
 	CamelLocalSummaryClass parent_class;
 
 	/* sync in-place */
-	gint (*sync_quick)(CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error);
+	gint		(*sync_quick)		(CamelMboxSummary *cls,
+						 gboolean expunge,
+						 CamelFolderChangeInfo *changeinfo,
+						 GCancellable *cancellable,
+						 GError **error);
+
 	/* sync requires copy */
-	gint (*sync_full)(CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error);
+	gint		(*sync_full)		(CamelMboxSummary *cls,
+						 gboolean expunge,
+						 CamelFolderChangeInfo *changeinfo,
+						 GCancellable *cancellable,
+						 GError **error);
 };
 
 GType		camel_mbox_summary_get_type	(void);
-CamelMboxSummary      *camel_mbox_summary_new	(struct _CamelFolder *, const gchar *filename, const gchar *mbox_name, CamelIndex *index);
+CamelMboxSummary *
+		camel_mbox_summary_new		(CamelFolder *folder,
+						 const gchar *filename,
+						 const gchar *mbox_name,
+						 CamelIndex *index);
 
-/* do we honour/use xstatus headers, etc */
-void camel_mbox_summary_xstatus (CamelMboxSummary *mbs, gint state);
+/* do we honor/use xstatus headers, etc */
+void		camel_mbox_summary_xstatus	(CamelMboxSummary *mbs,
+						 gint state);
 
 /* build a new mbox from an existing mbox storing summary information */
-gint camel_mbox_summary_sync_mbox (CamelMboxSummary *cls, guint32 flags, CamelFolderChangeInfo *changeinfo, gint fd, gint fdout, GError **error);
+gint		camel_mbox_summary_sync_mbox	(CamelMboxSummary *cls,
+						 guint32 flags,
+						 CamelFolderChangeInfo *changeinfo,
+						 gint fd,
+						 gint fdout,
+						 GCancellable *cancellable,
+						 GError **error);
 
 G_END_DECLS
 
diff --git a/camel/providers/local/camel-mh-folder.c b/camel/providers/local/camel-mh-folder.c
index 3e0752a..7b4cd1c 100644
--- a/camel/providers/local/camel-mh-folder.c
+++ b/camel/providers/local/camel-mh-folder.c
@@ -40,75 +40,15 @@
 
 #define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
 
-static CamelLocalSummary *mh_create_summary (CamelLocalFolder *lf, const gchar *path, const gchar *folder, CamelIndex *index);
-
-static gboolean mh_append_message (CamelFolder *folder, CamelMimeMessage * message, const CamelMessageInfo *info, gchar **appended_uid, GError **error);
-static CamelMimeMessage *mh_get_message (CamelFolder *folder, const gchar *uid, GError **error);
-static gchar * mh_get_filename (CamelFolder *folder, const gchar *uid, GError **error);
-
 G_DEFINE_TYPE (CamelMhFolder, camel_mh_folder, CAMEL_TYPE_LOCAL_FOLDER)
 
-static void
-camel_mh_folder_class_init (CamelMhFolderClass *class)
-{
-	CamelFolderClass *folder_class;
-	CamelLocalFolderClass *local_folder_class;
-
-	folder_class = CAMEL_FOLDER_CLASS (class);
-	folder_class->append_message = mh_append_message;
-	folder_class->get_message = mh_get_message;
-	folder_class->get_filename = mh_get_filename;
-
-	local_folder_class = CAMEL_LOCAL_FOLDER_CLASS (class);
-	local_folder_class->create_summary = mh_create_summary;
-}
-
-static void
-camel_mh_folder_init (CamelMhFolder *mh_folder)
-{
-}
-
-CamelFolder *
-camel_mh_folder_new (CamelStore *parent_store,
-                     const gchar *full_name,
-                     guint32 flags,
-                     GError **error)
-{
-	CamelFolder *folder;
-	gchar *basename;
-
-	d(printf("Creating mh folder: %s\n", full_name));
-
-	basename = g_path_get_basename (full_name);
-
-	folder = g_object_new (
-		CAMEL_TYPE_MH_FOLDER,
-		"name", basename, "full-name", full_name,
-		"parent-store", parent_store, NULL);
-	folder = (CamelFolder *) camel_local_folder_construct (
-		CAMEL_LOCAL_FOLDER (folder), flags, error);
-
-	g_free (basename);
-
-	return folder;
-}
-
-static CamelLocalSummary *
-mh_create_summary (CamelLocalFolder *lf,
-                   const gchar *path,
-                   const gchar *folder,
-                   CamelIndex *index)
-{
-	return (CamelLocalSummary *) camel_mh_summary_new (
-		CAMEL_FOLDER (lf), path, folder, index);
-}
-
 static gboolean
-mh_append_message (CamelFolder *folder,
-                   CamelMimeMessage *message,
-                   const CamelMessageInfo *info,
-                   gchar **appended_uid,
-                   GError **error)
+mh_folder_append_message (CamelFolder *folder,
+                          CamelMimeMessage *message,
+                          const CamelMessageInfo *info,
+                          gchar **appended_uid,
+                          GCancellable *cancellable,
+                          GError **error)
 {
 	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
 	CamelStream *output_stream;
@@ -141,8 +81,8 @@ mh_append_message (CamelFolder *folder,
 		goto fail_write;
 
 	if (camel_data_wrapper_write_to_stream (
-		(CamelDataWrapper *)message, output_stream, error) == -1
-	    || camel_stream_close (output_stream, error) == -1)
+		(CamelDataWrapper *)message, output_stream, cancellable, error) == -1
+	    || camel_stream_close (output_stream, cancellable, error) == -1)
 		goto fail_write;
 
 	/* close this? */
@@ -182,20 +122,11 @@ mh_append_message (CamelFolder *folder,
 	return TRUE;
 }
 
-static gchar *
-mh_get_filename (CamelFolder *folder,
-                 const gchar *uid,
-                 GError **error)
-{
-	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
-
-	return g_strdup_printf("%s/%s", lf->folder_path, uid);
-}
-
 static CamelMimeMessage *
-mh_get_message (CamelFolder *folder,
-                const gchar *uid,
-                GError **error)
+mh_folder_get_message (CamelFolder *folder,
+                       const gchar *uid,
+                       GCancellable *cancellable,
+                       GError **error)
 {
 	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
 	CamelStream *message_stream = NULL;
@@ -230,7 +161,7 @@ mh_get_message (CamelFolder *folder,
 	}
 
 	message = camel_mime_message_new ();
-	if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)message, message_stream, error) == -1) {
+	if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)message, message_stream, cancellable, error) == -1) {
 		g_prefix_error (
 			error, _("Cannot get message %s from folder %s: "),
 			name, lf->folder_path);
@@ -252,3 +183,70 @@ mh_get_message (CamelFolder *folder,
 
 	return message;
 }
+
+static gchar *
+mh_folder_get_filename (CamelFolder *folder,
+                        const gchar *uid,
+                        GError **error)
+{
+	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
+
+	return g_strdup_printf("%s/%s", lf->folder_path, uid);
+}
+
+static CamelLocalSummary *
+mh_folder_create_summary (CamelLocalFolder *lf,
+                          const gchar *path,
+                          const gchar *folder,
+                          CamelIndex *index)
+{
+	return (CamelLocalSummary *) camel_mh_summary_new (
+		CAMEL_FOLDER (lf), path, folder, index);
+}
+
+static void
+camel_mh_folder_class_init (CamelMhFolderClass *class)
+{
+	CamelFolderClass *folder_class;
+	CamelLocalFolderClass *local_folder_class;
+
+	folder_class = CAMEL_FOLDER_CLASS (class);
+	folder_class->append_message = mh_folder_append_message;
+	folder_class->get_message = mh_folder_get_message;
+	folder_class->get_filename = mh_folder_get_filename;
+
+	local_folder_class = CAMEL_LOCAL_FOLDER_CLASS (class);
+	local_folder_class->create_summary = mh_folder_create_summary;
+}
+
+static void
+camel_mh_folder_init (CamelMhFolder *mh_folder)
+{
+}
+
+CamelFolder *
+camel_mh_folder_new (CamelStore *parent_store,
+                     const gchar *full_name,
+                     guint32 flags,
+                     GCancellable *cancellable,
+                     GError **error)
+{
+	CamelFolder *folder;
+	gchar *basename;
+
+	d(printf("Creating mh folder: %s\n", full_name));
+
+	basename = g_path_get_basename (full_name);
+
+	folder = g_object_new (
+		CAMEL_TYPE_MH_FOLDER,
+		"name", basename, "full-name", full_name,
+		"parent-store", parent_store, NULL);
+	folder = (CamelFolder *) camel_local_folder_construct (
+		CAMEL_LOCAL_FOLDER (folder), flags, cancellable, error);
+
+	g_free (basename);
+
+	return folder;
+}
+
diff --git a/camel/providers/local/camel-mh-folder.h b/camel/providers/local/camel-mh-folder.h
index 11dbf4e..bb75e59 100644
--- a/camel/providers/local/camel-mh-folder.h
+++ b/camel/providers/local/camel-mh-folder.h
@@ -56,10 +56,12 @@ struct _CamelMhFolderClass {
 	CamelLocalFolderClass parent_class;
 };
 
-/* public methods */
-CamelFolder *camel_mh_folder_new (CamelStore *parent_store, const gchar *full_name, guint32 flags, GError **error);
-
-GType camel_mh_folder_get_type (void);
+GType		camel_mh_folder_get_type	(void);
+CamelFolder *	camel_mh_folder_new		(CamelStore *parent_store,
+						 const gchar *full_name,
+						 guint32 flags,
+						 GCancellable *cancellable,
+						 GError **error);
 
 G_END_DECLS
 
diff --git a/camel/providers/local/camel-mh-store.c b/camel/providers/local/camel-mh-store.c
index f64923b..a842bc2 100644
--- a/camel/providers/local/camel-mh-store.c
+++ b/camel/providers/local/camel-mh-store.c
@@ -39,11 +39,11 @@
 #define d(x)
 
 static gboolean construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, GError **error);
-static CamelFolder *get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError **error);
-static CamelFolder *get_inbox (CamelStore *store, GError **error);
-static gboolean delete_folder (CamelStore *store, const gchar *folder_name, GError **error);
-static gboolean rename_folder (CamelStore *store, const gchar *old, const gchar *new, GError **error);
-static CamelFolderInfo * get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GError **error);
+static CamelFolder *get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GCancellable *cancellable, GError **error);
+static CamelFolder *get_inbox (CamelStore *store, GCancellable *cancellable, GError **error);
+static gboolean delete_folder (CamelStore *store, const gchar *folder_name, GCancellable *cancellable, GError **error);
+static gboolean rename_folder (CamelStore *store, const gchar *old, const gchar *new, GCancellable *cancellable, GError **error);
+static CamelFolderInfo * get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GCancellable *cancellable, GError **error);
 
 G_DEFINE_TYPE (CamelMhStore, camel_mh_store, CAMEL_TYPE_LOCAL_STORE)
 
@@ -102,7 +102,8 @@ static void
 folders_update (const gchar *root,
                 gint mode,
                 const gchar *folder,
-                const gchar *new)
+                const gchar *new,
+                GCancellable *cancellable)
 {
 	gchar *tmp, *tmpnew, *line = NULL;
 	CamelStream *stream, *in = NULL, *out = NULL;
@@ -129,7 +130,7 @@ folders_update (const gchar *root,
 		goto done;
 	}
 
-	while ((line = camel_stream_buffer_read_line ((CamelStreamBuffer *)in, NULL))) {
+	while ((line = camel_stream_buffer_read_line ((CamelStreamBuffer *)in, cancellable, NULL))) {
 		gint copy = TRUE;
 
 		switch (mode) {
@@ -140,9 +141,9 @@ folders_update (const gchar *root,
 		case UPDATE_RENAME:
 			if (strncmp (line, folder, flen) == 0
 			    && (line[flen] == 0 || line[flen] == '/')) {
-				if (camel_stream_write (out, new, strlen (new), NULL) == -1
-				    || camel_stream_write (out, line+flen, strlen (line)-flen, NULL) == -1
-				    || camel_stream_write(out, "\n", 1, NULL) == -1)
+				if (camel_stream_write (out, new, strlen (new), cancellable, NULL) == -1
+				    || camel_stream_write (out, line+flen, strlen (line)-flen, cancellable, NULL) == -1
+				    || camel_stream_write(out, "\n", 1, cancellable, NULL) == -1)
 					goto fail;
 				copy = FALSE;
 			}
@@ -175,7 +176,7 @@ folders_update (const gchar *root,
 	if (mode == UPDATE_ADD && camel_stream_printf(out, "%s\n", folder) == -1)
 		goto fail;
 
-	if (camel_stream_close (out, NULL) == -1)
+	if (camel_stream_close (out, cancellable, NULL) == -1)
 		goto fail;
 
 done:
@@ -194,6 +195,7 @@ static CamelFolder *
 get_folder (CamelStore *store,
             const gchar *folder_name,
             guint32 flags,
+            GCancellable *cancellable,
             GError **error)
 {
 	CamelStoreClass *store_class;
@@ -202,7 +204,7 @@ get_folder (CamelStore *store,
 
 	/* Chain up to parent's get_folder() method. */
 	store_class = CAMEL_STORE_CLASS (camel_mh_store_parent_class);
-	if (store_class->get_folder (store, folder_name, flags, error) == NULL)
+	if (store_class->get_folder (store, folder_name, flags, cancellable, error) == NULL)
 		return NULL;
 
 	name = g_strdup_printf("%s%s", CAMEL_LOCAL_STORE(store)->toplevel_dir, folder_name);
@@ -240,7 +242,7 @@ get_folder (CamelStore *store,
 		/* add to .folders if we are supposed to */
 		/* FIXME: throw exception on error */
 		if (((CamelMhStore *)store)->flags & CAMEL_MH_DOTFOLDERS)
-			folders_update (((CamelLocalStore *)store)->toplevel_dir, UPDATE_ADD, folder_name, NULL);
+			folders_update (((CamelLocalStore *)store)->toplevel_dir, UPDATE_ADD, folder_name, NULL, cancellable);
 	} else if (!S_ISDIR (st.st_mode)) {
 		g_set_error (
 			error, CAMEL_STORE_ERROR,
@@ -260,19 +262,21 @@ get_folder (CamelStore *store,
 
 	g_free (name);
 
-	return camel_mh_folder_new (store, folder_name, flags, error);
+	return camel_mh_folder_new (store, folder_name, flags, cancellable, error);
 }
 
 static CamelFolder *
 get_inbox (CamelStore *store,
+           GCancellable *cancellable,
            GError **error)
 {
-	return get_folder (store, "inbox", 0, error);
+	return get_folder (store, "inbox", 0, cancellable, error);
 }
 
 static gboolean
 delete_folder (CamelStore *store,
                const gchar *folder_name,
+               GCancellable *cancellable,
                GError **error)
 {
 	CamelStoreClass *store_class;
@@ -293,29 +297,30 @@ delete_folder (CamelStore *store,
 
 	/* remove from .folders if we are supposed to */
 	if (((CamelMhStore *)store)->flags & CAMEL_MH_DOTFOLDERS)
-		folders_update (((CamelLocalStore *)store)->toplevel_dir, UPDATE_REMOVE, folder_name, NULL);
+		folders_update (((CamelLocalStore *)store)->toplevel_dir, UPDATE_REMOVE, folder_name, NULL, cancellable);
 
 	/* Chain up to parent's delete_folder() method. */
 	store_class = CAMEL_STORE_CLASS (camel_mh_store_parent_class);
-	return store_class->delete_folder (store, folder_name, error);
+	return store_class->delete_folder (store, folder_name, cancellable, error);
 }
 
 static gboolean
 rename_folder (CamelStore *store,
                const gchar *old,
                const gchar *new,
+               GCancellable *cancellable,
                GError **error)
 {
 	CamelStoreClass *store_class;
 
 	/* Chain up to parent's rename_folder() method. */
 	store_class = CAMEL_STORE_CLASS (camel_mh_store_parent_class);
-	if (!store_class->rename_folder (store, old, new, error))
+	if (!store_class->rename_folder (store, old, new, cancellable, error))
 		return FALSE;
 
 	if (((CamelMhStore *)store)->flags & CAMEL_MH_DOTFOLDERS) {
 		/* yeah this is messy, but so is mh! */
-		folders_update (((CamelLocalStore *)store)->toplevel_dir, UPDATE_RENAME, old, new);
+		folders_update (((CamelLocalStore *)store)->toplevel_dir, UPDATE_RENAME, old, new, cancellable);
 	}
 
 	return TRUE;
@@ -324,7 +329,8 @@ rename_folder (CamelStore *store,
 static void
 fill_fi (CamelStore *store,
          CamelFolderInfo *fi,
-         guint32 flags)
+         guint32 flags,
+         GCancellable *cancellable)
 {
 	CamelFolder *folder;
 
@@ -332,11 +338,11 @@ fill_fi (CamelStore *store,
 
 	if (folder == NULL
 	    && (flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0)
-		folder = camel_store_get_folder (store, fi->full_name, 0, NULL);
+		folder = camel_store_get_folder (store, fi->full_name, 0, cancellable, NULL);
 
 	if (folder) {
 		if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0)
-			camel_folder_refresh_info (folder, NULL);
+			camel_folder_refresh_info (folder, cancellable, NULL);
 		fi->unread = camel_folder_get_unread_message_count (folder);
 		fi->total = camel_folder_get_message_count (folder);
 		g_object_unref (folder);
@@ -370,7 +376,8 @@ folder_info_new (CamelStore *store,
                  CamelURL *url,
                  const gchar *root,
                  const gchar *path,
-                 guint32 flags)
+                 guint32 flags,
+                 GCancellable *cancellable)
 {
 	/* FIXME: need to set fi->flags = CAMEL_FOLDER_NOSELECT (and possibly others) when appropriate */
 	CamelFolderInfo *fi;
@@ -385,7 +392,7 @@ folder_info_new (CamelStore *store,
 	fi->uri = camel_url_to_string (url, 0);
 	fi->full_name = g_strdup (path);
 	fi->name = g_strdup (base?base+1:path);
-	fill_fi (store, fi, flags);
+	fill_fi (store, fi, flags, cancellable);
 
 	d(printf("New folderinfo:\n '%s'\n '%s'\n '%s'\n", fi->full_name, fi->uri, fi->path));
 
@@ -408,7 +415,8 @@ recursive_scan (CamelStore *store,
                 GHashTable *visited,
                 const gchar *root,
                 const gchar *path,
-                guint32 flags)
+                guint32 flags,
+                GCancellable *cancellable)
 {
 	gchar *fullpath, *tmp;
 	DIR *dp;
@@ -439,7 +447,7 @@ recursive_scan (CamelStore *store,
 	g_hash_table_insert (visited, inew, inew);
 
 	/* link in ... */
-	fi = folder_info_new (store, url, root, path, flags);
+	fi = folder_info_new (store, url, root, path, flags, cancellable);
 	fi->parent = parent;
 	fi->next = *fip;
 	*fip = fi;
@@ -465,10 +473,10 @@ recursive_scan (CamelStore *store,
 			/* otherwise, treat at potential node, and recurse, a bit more expensive than needed, but tough! */
 			if (path[0]) {
 				tmp = g_strdup_printf("%s/%s", path, d->d_name);
-				recursive_scan (store, url, &fi->child, fi, visited, root, tmp, flags);
+				recursive_scan (store, url, &fi->child, fi, visited, root, tmp, flags, cancellable);
 				g_free (tmp);
 			} else {
-				recursive_scan (store, url, &fi->child, fi, visited, root, d->d_name, flags);
+				recursive_scan (store, url, &fi->child, fi, visited, root, d->d_name, flags, cancellable);
 			}
 		}
 
@@ -483,7 +491,8 @@ folders_scan (CamelStore *store,
               const gchar *root,
               const gchar *top,
               CamelFolderInfo **fip,
-              guint32 flags)
+              guint32 flags,
+              GCancellable *cancellable)
 {
 	CamelFolderInfo *fi;
 	gchar  line[512], *path, *tmp;
@@ -507,7 +516,7 @@ folders_scan (CamelStore *store,
 	visited = g_hash_table_new (g_str_hash, g_str_equal);
 	folders = g_ptr_array_new ();
 
-	while ( (len = camel_stream_buffer_gets ((CamelStreamBuffer *)in, line, sizeof (line), NULL)) > 0) {
+	while ( (len = camel_stream_buffer_gets ((CamelStreamBuffer *)in, line, sizeof (line), cancellable, NULL)) > 0) {
 		/* ignore blank lines */
 		if (len <= 1)
 			continue;
@@ -547,7 +556,7 @@ folders_scan (CamelStore *store,
 
 		path = g_strdup_printf("%s/%s", root, line);
 		if (g_stat (path, &st) == 0 && S_ISDIR (st.st_mode)) {
-			fi = folder_info_new (store, url, root, line, flags);
+			fi = folder_info_new (store, url, root, line, flags, cancellable);
 			g_ptr_array_add (folders, fi);
 		}
 		g_free (path);
@@ -590,6 +599,7 @@ static CamelFolderInfo *
 get_folder_info (CamelStore *store,
                  const gchar *top,
                  guint32 flags,
+                 GCancellable *cancellable,
                  GError **error)
 {
 	CamelFolderInfo *fi = NULL;
@@ -602,14 +612,14 @@ get_folder_info (CamelStore *store,
 
 	/* use .folders if we are supposed to */
 	if (((CamelMhStore *)store)->flags & CAMEL_MH_DOTFOLDERS) {
-		folders_scan (store, url, root, top, &fi, flags);
+		folders_scan (store, url, root, top, &fi, flags, cancellable);
 	} else {
 		GHashTable *visited = g_hash_table_new (inode_hash, inode_equal);
 
 		if (top == NULL)
 			top = "";
 
-		recursive_scan (store, url, &fi, NULL, visited, root, top, flags);
+		recursive_scan (store, url, &fi, NULL, visited, root, top, flags, cancellable);
 
 		/* if we actually scanned from root, we have a "" root node we dont want */
 		if (fi != NULL && top[0] == 0) {
diff --git a/camel/providers/local/camel-mh-summary.c b/camel/providers/local/camel-mh-summary.c
index 033be93..fa693e8 100644
--- a/camel/providers/local/camel-mh-summary.c
+++ b/camel/providers/local/camel-mh-summary.c
@@ -45,8 +45,8 @@
 	(G_TYPE_INSTANCE_GET_PRIVATE \
 	((obj), CAMEL_TYPE_MH_SUMMARY, CamelMhSummaryPrivate))
 
-static gint mh_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GError **error);
-static gint mh_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error);
+static gint mh_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error);
+static gint mh_summary_sync (CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error);
 /*static gint mh_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, CamelMessageInfo *info, CamelFolderChangeInfo *, GError **error);*/
 
 static gchar *mh_summary_next_uid_string (CamelFolderSummary *s);
@@ -155,7 +155,8 @@ mh_summary_next_uid_string (CamelFolderSummary *s)
 static gint
 camel_mh_summary_add (CamelLocalSummary *cls,
                       const gchar *name,
-                      gint forceindex)
+                      gint forceindex,
+                      GCancellable *cancellable)
 {
 	CamelMhSummary *mhs = (CamelMhSummary *)cls;
 	gchar *filename = g_strdup_printf("%s/%s", cls->folder_path, name);
@@ -203,6 +204,7 @@ remove_summary (gchar *key,
 static gint
 mh_summary_check (CamelLocalSummary *cls,
                   CamelFolderChangeInfo *changeinfo,
+                  GCancellable *cancellable,
                   GError **error)
 {
 	DIR *dir;
@@ -258,7 +260,7 @@ mh_summary_check (CamelLocalSummary *cls,
 					camel_folder_summary_remove ((CamelFolderSummary *)cls, info);
 					camel_message_info_free (info);
 				}
-				camel_mh_summary_add (cls, d->d_name, forceindex);
+				camel_mh_summary_add (cls, d->d_name, forceindex, cancellable);
 			} else {
 				const gchar *uid = camel_message_info_uid (info);
 				CamelMessageInfo *old = g_hash_table_lookup (left, uid);
@@ -287,6 +289,7 @@ static gint
 mh_summary_sync (CamelLocalSummary *cls,
                  gboolean expunge,
                  CamelFolderChangeInfo *changes,
+                 GCancellable *cancellable,
                  GError **error)
 {
 	CamelLocalSummaryClass *local_summary_class;
@@ -299,7 +302,7 @@ mh_summary_sync (CamelLocalSummary *cls,
 
 	/* we could probably get away without this ... but why not use it, esp if we're going to
 	   be doing any significant io already */
-	if (camel_local_summary_check (cls, changes, error) == -1)
+	if (camel_local_summary_check (cls, changes, cancellable, error) == -1)
 		return -1;
 
 	/* FIXME: need to update/honour .mh_sequences or whatever it is */
@@ -331,5 +334,5 @@ mh_summary_sync (CamelLocalSummary *cls,
 
 	/* Chain up to parent's sync() method. */
 	local_summary_class = CAMEL_LOCAL_SUMMARY_CLASS (camel_mh_summary_parent_class);
-	return local_summary_class->sync (cls, expunge, changes, error);
+	return local_summary_class->sync (cls, expunge, changes, cancellable, error);
 }
diff --git a/camel/providers/local/camel-spool-folder.c b/camel/providers/local/camel-spool-folder.c
index 1923c32..8063002 100644
--- a/camel/providers/local/camel-spool-folder.c
+++ b/camel/providers/local/camel-spool-folder.c
@@ -40,77 +40,22 @@
 
 #define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
 
-static CamelLocalSummary *spool_create_summary (CamelLocalFolder *lf, const gchar *path, const gchar *folder, CamelIndex *index);
-
-static gint spool_lock (CamelLocalFolder *lf, CamelLockType type, GError **error);
-static void spool_unlock (CamelLocalFolder *lf);
-
 G_DEFINE_TYPE (CamelSpoolFolder, camel_spool_folder, CAMEL_TYPE_MBOX_FOLDER)
 
-static void
-camel_spool_folder_class_init (CamelSpoolFolderClass *class)
-{
-	CamelLocalFolderClass *local_folder_class;
-
-	local_folder_class = CAMEL_LOCAL_FOLDER_CLASS (class);
-	local_folder_class->create_summary = spool_create_summary;
-	local_folder_class->lock = spool_lock;
-	local_folder_class->unlock = spool_unlock;
-}
-
-static void
-camel_spool_folder_init (CamelSpoolFolder *spool_folder)
-{
-	spool_folder->lockid = -1;
-}
-
-CamelFolder *
-camel_spool_folder_new (CamelStore *parent_store,
-                        const gchar *full_name,
-                        guint32 flags,
-                        GError **error)
-{
-	CamelFolder *folder;
-	gchar *basename;
-
-	basename = g_path_get_basename (full_name);
-
-	folder = g_object_new (
-		CAMEL_TYPE_SPOOL_FOLDER,
-		"name", basename, "full-name", full_name,
-		"parent-store", parent_store, NULL);
-
-	if (parent_store->flags & CAMEL_STORE_FILTER_INBOX
-	    && strcmp(full_name, "INBOX") == 0)
-		folder->folder_flags |= CAMEL_FOLDER_FILTER_RECENT;
-	flags &= ~CAMEL_STORE_FOLDER_BODY_INDEX;
-
-	folder = (CamelFolder *)camel_local_folder_construct (
-		(CamelLocalFolder *)folder, flags, error);
-	if (folder) {
-		if (camel_url_get_param(((CamelService *)parent_store)->url, "xstatus"))
-			camel_mbox_summary_xstatus ((CamelMboxSummary *)folder->summary, TRUE);
-	}
-
-	g_free (basename);
-
-	return folder;
-}
-
 static CamelLocalSummary *
-spool_create_summary (CamelLocalFolder *lf,
-                      const gchar *path,
-                      const gchar *folder,
-                      CamelIndex *index)
+spool_folder_create_summary (CamelLocalFolder *lf,
+                             const gchar *path,
+                             const gchar *folder,
+                             CamelIndex *index)
 {
 	return (CamelLocalSummary *) camel_spool_summary_new (
 		CAMEL_FOLDER (lf), folder);
 }
 
 static gint
-spool_lock (CamelLocalFolder *lf,
-            CamelLockType type,
-            GError **error)
+spool_folder_lock (CamelLocalFolder *lf,
+                   CamelLockType type,
+                   GError **error)
 {
 	gint retry = 0;
 	CamelMboxFolder *mf = (CamelMboxFolder *)lf;
@@ -154,7 +99,7 @@ spool_lock (CamelLocalFolder *lf,
 }
 
 static void
-spool_unlock (CamelLocalFolder *lf)
+spool_folder_unlock (CamelLocalFolder *lf)
 {
 	CamelMboxFolder *mf = (CamelMboxFolder *)lf;
 	CamelSpoolFolder *sf = (CamelSpoolFolder *)lf;
@@ -167,3 +112,55 @@ spool_unlock (CamelLocalFolder *lf)
 	close (mf->lockfd);
 	mf->lockfd = -1;
 }
+
+static void
+camel_spool_folder_class_init (CamelSpoolFolderClass *class)
+{
+	CamelLocalFolderClass *local_folder_class;
+
+	local_folder_class = CAMEL_LOCAL_FOLDER_CLASS (class);
+	local_folder_class->create_summary = spool_folder_create_summary;
+	local_folder_class->lock = spool_folder_lock;
+	local_folder_class->unlock = spool_folder_unlock;
+}
+
+static void
+camel_spool_folder_init (CamelSpoolFolder *spool_folder)
+{
+	spool_folder->lockid = -1;
+}
+
+CamelFolder *
+camel_spool_folder_new (CamelStore *parent_store,
+                        const gchar *full_name,
+                        guint32 flags,
+                        GCancellable *cancellable,
+                        GError **error)
+{
+	CamelFolder *folder;
+	gchar *basename;
+
+	basename = g_path_get_basename (full_name);
+
+	folder = g_object_new (
+		CAMEL_TYPE_SPOOL_FOLDER,
+		"name", basename, "full-name", full_name,
+		"parent-store", parent_store, NULL);
+
+	if (parent_store->flags & CAMEL_STORE_FILTER_INBOX
+	    && strcmp(full_name, "INBOX") == 0)
+		folder->folder_flags |= CAMEL_FOLDER_FILTER_RECENT;
+	flags &= ~CAMEL_STORE_FOLDER_BODY_INDEX;
+
+	folder = (CamelFolder *)camel_local_folder_construct (
+		(CamelLocalFolder *)folder, flags, cancellable, error);
+	if (folder) {
+		if (camel_url_get_param(((CamelService *)parent_store)->url, "xstatus"))
+			camel_mbox_summary_xstatus ((CamelMboxSummary *)folder->summary, TRUE);
+	}
+
+	g_free (basename);
+
+	return folder;
+}
+
diff --git a/camel/providers/local/camel-spool-folder.h b/camel/providers/local/camel-spool-folder.h
index fd96fe0..b7b0bbb 100644
--- a/camel/providers/local/camel-spool-folder.h
+++ b/camel/providers/local/camel-spool-folder.h
@@ -61,9 +61,12 @@ struct _CamelSpoolFolderClass {
 	CamelMboxFolderClass parent_class;
 };
 
-GType camel_spool_folder_get_type (void);
-
-CamelFolder *camel_spool_folder_new (CamelStore *parent_store, const gchar *full_name, guint32 flags, GError **error);
+GType		camel_spool_folder_get_type	(void);
+CamelFolder *	camel_spool_folder_new		(CamelStore *parent_store,
+						 const gchar *full_name,
+						 guint32 flags,
+						 GCancellable *cancellable,
+						 GError **error);
 
 G_END_DECLS
 
diff --git a/camel/providers/local/camel-spool-store.c b/camel/providers/local/camel-spool-store.c
index b5f8e77..04f173f 100644
--- a/camel/providers/local/camel-spool-store.c
+++ b/camel/providers/local/camel-spool-store.c
@@ -41,14 +41,14 @@
 #define d(x)
 
 static gboolean construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, GError **error);
-static CamelFolder *get_folder (CamelStore* store, const gchar *folder_name, guint32 flags, GError **error);
+static CamelFolder *get_folder (CamelStore* store, const gchar *folder_name, guint32 flags, GCancellable *cancellable, GError **error);
 static gchar *get_name (CamelService *service, gboolean brief);
-static CamelFolder *get_inbox (CamelStore *store, GError **error);
-static gboolean rename_folder (CamelStore *store, const gchar *old_name, const gchar *new_name, GError **error);
-static CamelFolderInfo *get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GError **error);
+static CamelFolder *get_inbox (CamelStore *store, GCancellable *cancellable, GError **error);
+static gboolean rename_folder (CamelStore *store, const gchar *old_name, const gchar *new_name, GCancellable *cancellable, GError **error);
+static CamelFolderInfo *get_folder_info (CamelStore *store, const gchar *top, guint32 flags, GCancellable *cancellable, GError **error);
 static void free_folder_info (CamelStore *store, CamelFolderInfo *fi);
 
-static gboolean delete_folder (CamelStore *store, const gchar *folder_name, GError **error);
+static gboolean delete_folder (CamelStore *store, const gchar *folder_name, GCancellable *cancellable, GError **error);
 
 static gchar *spool_get_meta_path (CamelLocalStore *ls, const gchar *full_name, const gchar *ext);
 static gchar *spool_get_full_path (CamelLocalStore *ls, const gchar *full_name);
@@ -141,6 +141,7 @@ static CamelFolder *
 get_folder (CamelStore *store,
             const gchar *folder_name,
             guint32 flags,
+            GCancellable *cancellable,
             GError **error)
 {
 	CamelFolder *folder = NULL;
@@ -158,7 +159,7 @@ get_folder (CamelStore *store,
 				_("Folder '%s/%s' does not exist."),
 				((CamelService *)store)->url->path, folder_name);
 		} else {
-			folder = camel_spool_folder_new (store, folder_name, flags, error);
+			folder = camel_spool_folder_new (store, folder_name, flags, cancellable, error);
 		}
 	} else {
 		name = g_strdup_printf("%s%s", CAMEL_LOCAL_STORE(store)->toplevel_dir, folder_name);
@@ -183,7 +184,7 @@ get_folder (CamelStore *store,
 						_("Could not create folder '%s':\n%s"),
 						folder_name, g_strerror (errno));
 				} else {
-					folder = camel_spool_folder_new (store, folder_name, flags, error);
+					folder = camel_spool_folder_new (store, folder_name, flags, cancellable, error);
 				}
 			}
 		} else if (!S_ISREG (st.st_mode)) {
@@ -192,7 +193,7 @@ get_folder (CamelStore *store,
 				CAMEL_STORE_ERROR_NO_FOLDER,
 				_("'%s' is not a mailbox file."), name);
 		} else {
-			folder = camel_spool_folder_new (store, folder_name, flags, error);
+			folder = camel_spool_folder_new (store, folder_name, flags, cancellable, error);
 		}
 		g_free (name);
 	}
@@ -202,10 +203,11 @@ get_folder (CamelStore *store,
 
 static CamelFolder *
 get_inbox (CamelStore *store,
+           GCancellable *cancellable,
            GError **error)
 {
 	if (((CamelSpoolStore *)store)->type == CAMEL_SPOOL_STORE_MBOX)
-		return get_folder (store, "INBOX", CAMEL_STORE_FOLDER_CREATE, error);
+		return get_folder (store, "INBOX", CAMEL_STORE_FOLDER_CREATE, cancellable, error);
 	else {
 		g_set_error (
 			error, CAMEL_STORE_ERROR,
@@ -231,6 +233,7 @@ static gboolean
 rename_folder (CamelStore *store,
                const gchar *old,
                const gchar *new,
+               GCancellable *cancellable,
                GError **error)
 {
 	g_set_error (
@@ -244,6 +247,7 @@ rename_folder (CamelStore *store,
 static gboolean
 delete_folder (CamelStore *store,
                const gchar *folder_name,
+               GCancellable *cancellable,
                GError **error)
 {
 	g_set_error (
@@ -269,7 +273,8 @@ free_folder_info (CamelStore *store,
 static void
 spool_fill_fi (CamelStore *store,
                CamelFolderInfo *fi,
-               guint32 flags)
+               guint32 flags,
+               GCancellable *cancellable)
 {
 	CamelFolder *folder;
 
@@ -278,7 +283,7 @@ spool_fill_fi (CamelStore *store,
 	folder = camel_object_bag_get (store->folders, fi->full_name);
 	if (folder) {
 		if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0)
-			camel_folder_refresh_info (folder, NULL);
+			camel_folder_refresh_info (folder, cancellable, NULL);
 		fi->unread = camel_folder_get_unread_message_count (folder);
 		fi->total = camel_folder_get_message_count (folder);
 		g_object_unref (folder);
@@ -337,6 +342,7 @@ scan_dir (CamelStore *store,
           guint32 flags,
           CamelFolderInfo *parent,
           CamelFolderInfo **fip,
+          GCancellable *cancellable,
           GError **error)
 {
 	DIR *dir;
@@ -367,7 +373,7 @@ scan_dir (CamelStore *store,
 		/* incase we start scanning from a file.  messy duplication :-/ */
 		if (path) {
 			fi = spool_new_fi (store, parent, fip, path, CAMEL_FOLDER_NOINFERIORS|CAMEL_FOLDER_NOCHILDREN);
-			spool_fill_fi (store, fi, flags);
+			spool_fill_fi (store, fi, flags, cancellable);
 		}
 		return 0;
 	}
@@ -417,7 +423,7 @@ scan_dir (CamelStore *store,
 
 				if (folder != NULL || isfolder) {
 					fi = spool_new_fi (store, parent, fip, fname, CAMEL_FOLDER_NOINFERIORS|CAMEL_FOLDER_NOCHILDREN);
-					spool_fill_fi (store, fi, flags);
+					spool_fill_fi (store, fi, flags, cancellable);
 				}
 				if (folder)
 					g_object_unref (folder);
@@ -432,7 +438,7 @@ scan_dir (CamelStore *store,
 					*inew = in;
 					g_hash_table_insert (visited, inew, inew);
 
-					if (scan_dir (store, visited, root, fname, flags, parent, fip, error) == -1) {
+					if (scan_dir (store, visited, root, fname, flags, parent, fip, cancellable, error) == -1) {
 						g_free (tmp);
 						g_free (fname);
 						closedir (dir);
@@ -476,6 +482,7 @@ static CamelFolderInfo *
 get_folder_info_elm (CamelStore *store,
                      const gchar *top,
                      guint32 flags,
+                     GCancellable *cancellable,
                      GError **error)
 {
 	CamelFolderInfo *fi = NULL;
@@ -483,7 +490,7 @@ get_folder_info_elm (CamelStore *store,
 
 	visited = g_hash_table_new (inode_hash, inode_equal);
 
-	if (scan_dir (store, visited, ((CamelService *)store)->url->path, top, flags, NULL, &fi, error) == -1 && fi != NULL) {
+	if (scan_dir (store, visited, ((CamelService *)store)->url->path, top, flags, NULL, &fi, cancellable, error) == -1 && fi != NULL) {
 		camel_store_free_folder_info_full (store, fi);
 		fi = NULL;
 	}
@@ -498,6 +505,7 @@ static CamelFolderInfo *
 get_folder_info_mbox (CamelStore *store,
                       const gchar *top,
                       guint32 flags,
+                      GCancellable *cancellable,
                       GError **error)
 {
 	CamelFolderInfo *fi = NULL, *fip = NULL;
@@ -506,7 +514,7 @@ get_folder_info_mbox (CamelStore *store,
 		fi = spool_new_fi(store, NULL, &fip, "INBOX", CAMEL_FOLDER_NOINFERIORS|CAMEL_FOLDER_NOCHILDREN|CAMEL_FOLDER_SYSTEM);
 		g_free (fi->name);
 		fi->name = g_strdup(_("Inbox"));
-		spool_fill_fi (store, fi, flags);
+		spool_fill_fi (store, fi, flags, cancellable);
 	}
 
 	return fi;
@@ -516,12 +524,13 @@ static CamelFolderInfo *
 get_folder_info (CamelStore *store,
                  const gchar *top,
                  guint32 flags,
+                 GCancellable *cancellable,
                  GError **error)
 {
 	if (((CamelSpoolStore *)store)->type == CAMEL_SPOOL_STORE_MBOX)
-		return get_folder_info_mbox (store, top, flags, error);
+		return get_folder_info_mbox (store, top, flags, cancellable, error);
 	else
-		return get_folder_info_elm (store, top, flags, error);
+		return get_folder_info_elm (store, top, flags, cancellable, error);
 }
 
 static gchar *
diff --git a/camel/providers/local/camel-spool-summary.c b/camel/providers/local/camel-spool-summary.c
index 57e02a4..30fc168 100644
--- a/camel/providers/local/camel-spool-summary.c
+++ b/camel/providers/local/camel-spool-summary.c
@@ -45,9 +45,9 @@
 #define CAMEL_SPOOL_SUMMARY_VERSION (0x400)
 
 static gint spool_summary_load (CamelLocalSummary *cls, gint forceindex, GError **error);
-static gint spool_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GError **error);
+static gint spool_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error);
 
-static gint spool_summary_sync_full (CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GError **error);
+static gint spool_summary_sync_full (CamelMboxSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error);
 static gint spool_summary_need_index (void);
 
 G_DEFINE_TYPE (CamelSpoolSummary, camel_spool_summary, CAMEL_TYPE_MBOX_SUMMARY)
@@ -115,6 +115,7 @@ static gint
 spool_summary_sync_full (CamelMboxSummary *cls,
                          gboolean expunge,
                          CamelFolderChangeInfo *changeinfo,
+                         GCancellable *cancellable,
                          GError **error)
 {
 	gint fd = -1, fdout = -1;
@@ -127,7 +128,7 @@ spool_summary_sync_full (CamelMboxSummary *cls,
 
 	d(printf("performing full summary/sync\n"));
 
-	camel_operation_start(NULL, _("Storing folder"));
+	camel_operation_start (cancellable, _("Storing folder"));
 
 	fd = open (((CamelLocalSummary *)cls)->folder_path, O_RDWR|O_LARGEFILE);
 	if (fd == -1) {
@@ -137,7 +138,7 @@ spool_summary_sync_full (CamelMboxSummary *cls,
 			_("Could not open file: %s: %s"),
 			((CamelLocalSummary *)cls)->folder_path,
 			g_strerror (errno));
-		camel_operation_end (NULL);
+		camel_operation_end (cancellable);
 		return -1;
 	}
 
@@ -154,7 +155,9 @@ spool_summary_sync_full (CamelMboxSummary *cls,
 		goto error;
 	}
 
-	if (camel_mbox_summary_sync_mbox ((CamelMboxSummary *)cls, flags, changeinfo, fd, fdout, error) == -1)
+	if (camel_mbox_summary_sync_mbox (
+		(CamelMboxSummary *)cls, flags, changeinfo,
+		fd, fdout, cancellable, error) == -1)
 		goto error;
 
 	/* sync out content */
@@ -283,7 +286,7 @@ spool_summary_sync_full (CamelMboxSummary *cls,
 	if (tmpname[0] != '\0')
 		unlink (tmpname);
 
-	camel_operation_end (NULL);
+	camel_operation_end (cancellable);
 
 	return 0;
  error:
@@ -296,7 +299,7 @@ spool_summary_sync_full (CamelMboxSummary *cls,
 	if (tmpname[0] != '\0')
 		unlink (tmpname);
 
-	camel_operation_end (NULL);
+	camel_operation_end (cancellable);
 
 	return -1;
 }
@@ -304,13 +307,14 @@ spool_summary_sync_full (CamelMboxSummary *cls,
 static gint
 spool_summary_check (CamelLocalSummary *cls,
                      CamelFolderChangeInfo *changeinfo,
+                     GCancellable *cancellable,
                      GError **error)
 {
 	gint i, work, count;
 	struct stat st;
 	CamelFolderSummary *s = (CamelFolderSummary *)cls;
 
-	if (CAMEL_LOCAL_SUMMARY_CLASS (camel_spool_summary_parent_class)->check (cls, changeinfo, error) == -1)
+	if (CAMEL_LOCAL_SUMMARY_CLASS (camel_spool_summary_parent_class)->check (cls, changeinfo, cancellable, error) == -1)
 		return -1;
 
 	/* check to see if we need to copy/update the file; missing xev headers prompt this */
@@ -327,7 +331,9 @@ spool_summary_check (CamelLocalSummary *cls,
 	/* if we do, then write out the headers using sync_full, etc */
 	if (work) {
 		d(printf("Have to add new headers, re-syncing from the start to accomplish this\n"));
-		if (CAMEL_MBOX_SUMMARY_GET_CLASS (cls)->sync_full (CAMEL_MBOX_SUMMARY (cls), FALSE, changeinfo, error) == -1)
+		if (CAMEL_MBOX_SUMMARY_GET_CLASS (cls)->sync_full (
+			CAMEL_MBOX_SUMMARY (cls), FALSE,
+			changeinfo, cancellable, error) == -1)
 			return -1;
 
 		if (g_stat (cls->folder_path, &st) == -1) {
diff --git a/camel/providers/nntp/camel-nntp-folder.c b/camel/providers/nntp/camel-nntp-folder.c
index 08ed6f2..14c1757 100644
--- a/camel/providers/nntp/camel-nntp-folder.c
+++ b/camel/providers/nntp/camel-nntp-folder.c
@@ -72,6 +72,7 @@ nntp_folder_finalize (GObject *object)
 gboolean
 camel_nntp_folder_selected (CamelNNTPFolder *nntp_folder,
                             gchar *line,
+                            GCancellable *cancellable,
                             GError **error)
 {
 	CamelFolder *folder;
@@ -83,11 +84,13 @@ camel_nntp_folder_selected (CamelNNTPFolder *nntp_folder,
 	return camel_nntp_summary_check (
 		CAMEL_NNTP_SUMMARY (folder->summary),
 		CAMEL_NNTP_STORE (parent_store),
-		line, nntp_folder->changes, error);
+		line, nntp_folder->changes,
+		cancellable, error);
 }
 
 static gboolean
 nntp_folder_refresh_info_online (CamelFolder *folder,
+                                 GCancellable *cancellable,
                                  GError **error)
 {
 	CamelStore *parent_store;
@@ -107,7 +110,7 @@ nntp_folder_refresh_info_online (CamelFolder *folder,
 	/* When invoked with no fmt, camel_nntp_command() just selects the folder
 	   and should return zero. */
 	success = !camel_nntp_command (
-		nntp_store, error, nntp_folder, &line, NULL);
+		nntp_store, cancellable, error, nntp_folder, &line, NULL);
 
 	if (camel_folder_change_info_changed (nntp_folder->changes)) {
 		changes = nntp_folder->changes;
@@ -203,7 +206,11 @@ nntp_get_filename (CamelFolder *folder, const gchar *uid, GError **error)
 }
 
 static CamelStream *
-nntp_folder_download_message (CamelNNTPFolder *nntp_folder, const gchar *id, const gchar *msgid, GError **error)
+nntp_folder_download_message (CamelNNTPFolder *nntp_folder,
+                              const gchar *id,
+                              const gchar *msgid,
+                              GCancellable *cancellable,
+                              GError **error)
 {
 	CamelFolder *folder;
 	CamelStore *parent_store;
@@ -216,11 +223,11 @@ nntp_folder_download_message (CamelNNTPFolder *nntp_folder, const gchar *id, con
 	parent_store = camel_folder_get_parent_store (folder);
 	nntp_store = CAMEL_NNTP_STORE (parent_store);
 
-	ret = camel_nntp_command (nntp_store, error, nntp_folder, &line, "article %s", id);
+	ret = camel_nntp_command (nntp_store, cancellable, error, nntp_folder, &line, "article %s", id);
 	if (ret == 220) {
 		stream = camel_data_cache_add (nntp_store->cache, "cache", msgid, NULL);
 		if (stream) {
-			if (camel_stream_write_to_stream ((CamelStream *) nntp_store->stream, stream, error) == -1)
+			if (camel_stream_write_to_stream ((CamelStream *) nntp_store->stream, stream, cancellable, error) == -1)
 				goto fail;
 			if (camel_stream_reset (stream, error) == -1)
 				goto fail;
@@ -249,6 +256,7 @@ fail:
 static gboolean
 nntp_folder_cache_message (CamelDiscoFolder *disco_folder,
                            const gchar *uid,
+                           GCancellable *cancellable,
                            GError **error)
 {
 	CamelFolder *folder;
@@ -276,7 +284,7 @@ nntp_folder_cache_message (CamelDiscoFolder *disco_folder,
 	camel_service_lock (CAMEL_SERVICE (nntp_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
 	stream = nntp_folder_download_message (
-		(CamelNNTPFolder *) disco_folder, article, msgid, error);
+		(CamelNNTPFolder *) disco_folder, article, msgid, cancellable, error);
 	if (stream)
 		g_object_unref (stream);
 	else
@@ -288,7 +296,10 @@ nntp_folder_cache_message (CamelDiscoFolder *disco_folder,
 }
 
 static CamelMimeMessage *
-nntp_folder_get_message (CamelFolder *folder, const gchar *uid, GError **error)
+nntp_folder_get_message (CamelFolder *folder,
+                         const gchar *uid,
+                         GCancellable *cancellable,
+                         GError **error)
 {
 	CamelStore *parent_store;
 	CamelMimeMessage *message = NULL;
@@ -327,13 +338,13 @@ nntp_folder_get_message (CamelFolder *folder, const gchar *uid, GError **error)
 			goto fail;
 		}
 
-		stream = nntp_folder_download_message (nntp_folder, article, msgid, error);
+		stream = nntp_folder_download_message (nntp_folder, article, msgid, cancellable, error);
 		if (stream == NULL)
 			goto fail;
 	}
 
 	message = camel_mime_message_new ();
-	if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) message, stream, error) == -1) {
+	if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) message, stream, cancellable, error) == -1) {
 		g_prefix_error (error, _("Cannot get message %s: "), uid);
 		g_object_unref (message);
 		message = NULL;
@@ -433,6 +444,7 @@ nntp_folder_append_message_online (CamelFolder *folder,
                                    CamelMimeMessage *mime_message,
                                    const CamelMessageInfo *info,
                                    gchar **appended_uid,
+                                   GCancellable *cancellable,
                                    GError **error)
 {
 	CamelStore *parent_store;
@@ -456,7 +468,7 @@ nntp_folder_append_message_online (CamelFolder *folder,
 	camel_service_lock (CAMEL_SERVICE (nntp_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
 	/* send 'POST' command */
-	ret = camel_nntp_command (nntp_store, error, NULL, &line, "post");
+	ret = camel_nntp_command (nntp_store, cancellable, error, NULL, &line, "post");
 	if (ret != 340) {
 		if (ret == 440) {
 			g_set_error (
@@ -505,11 +517,11 @@ nntp_folder_append_message_online (CamelFolder *folder,
 	}
 
 	/* write the message */
-	if (camel_stream_write (stream, group, strlen (group), error) == -1
-	    || camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (mime_message), filtered_stream, error) == -1
-	    || camel_stream_flush (filtered_stream, error) == -1
-	    || camel_stream_write (stream, "\r\n.\r\n", 5, error) == -1
-	    || (ret = camel_nntp_stream_line (nntp_store->stream, (guchar **)&line, &u, error)) == -1) {
+	if (camel_stream_write (stream, group, strlen (group), cancellable, error) == -1
+	    || camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (mime_message), filtered_stream, cancellable, error) == -1
+	    || camel_stream_flush (filtered_stream, cancellable, error) == -1
+	    || camel_stream_write (stream, "\r\n.\r\n", 5, cancellable, error) == -1
+	    || (ret = camel_nntp_stream_line (nntp_store->stream, (guchar **)&line, &u, cancellable, error)) == -1) {
 		g_prefix_error (error, _("Posting failed: "));
 		success = FALSE;
 	} else if (atoi (line) != 240) {
@@ -533,6 +545,7 @@ nntp_folder_append_message_offline (CamelFolder *folder,
                                     CamelMimeMessage *mime_message,
                                     const CamelMessageInfo *info,
                                     gchar **appended_uid,
+                                    GCancellable *cancellable,
                                     GError **error)
 {
 	g_set_error (
@@ -552,6 +565,7 @@ nntp_folder_transfer_message (CamelFolder *source,
                               CamelFolder *dest,
                               GPtrArray **transferred_uids,
                               gboolean delete_orig,
+                              GCancellable *cancellable,
                               GError **error)
 {
 	g_set_error (
@@ -610,6 +624,7 @@ camel_nntp_folder_init (CamelNNTPFolder *nntp_folder)
 CamelFolder *
 camel_nntp_folder_new (CamelStore *parent,
                        const gchar *folder_name,
+                       GCancellable *cancellable,
                        GError **error)
 {
 	CamelFolder *folder;
@@ -656,7 +671,8 @@ camel_nntp_folder_new (CamelStore *parent,
 		camel_store_summary_info_free ((CamelStoreSummary *) ((CamelNNTPStore*) parent)->summary, si);
 	}
 
-	if (subscribed && !camel_folder_refresh_info (folder, error)) {
+	if (subscribed && !camel_folder_refresh_info (
+			folder, cancellable, error)) {
 		g_object_unref (folder);
 		folder = NULL;
         }
diff --git a/camel/providers/nntp/camel-nntp-folder.h b/camel/providers/nntp/camel-nntp-folder.h
index 4a72539..2f6a226 100644
--- a/camel/providers/nntp/camel-nntp-folder.h
+++ b/camel/providers/nntp/camel-nntp-folder.h
@@ -66,11 +66,15 @@ struct _CamelNNTPFolderClass {
 	CamelDiscoFolderClass parent;
 };
 
-GType camel_nntp_folder_get_type (void);
-
-CamelFolder *camel_nntp_folder_new (CamelStore *parent, const gchar *folder_name, GError **error);
-
-gboolean camel_nntp_folder_selected (CamelNNTPFolder *folder, gchar *line, GError **error);
+GType		camel_nntp_folder_get_type	(void);
+CamelFolder *	camel_nntp_folder_new		(CamelStore *parent,
+						 const gchar *folder_name,
+						 GCancellable *cancellable,
+						 GError **error);
+gboolean	camel_nntp_folder_selected	(CamelNNTPFolder *folder,
+						 gchar *line,
+						 GCancellable *cancellable,
+						 GError **error);
 
 G_END_DECLS
 
diff --git a/camel/providers/nntp/camel-nntp-store.c b/camel/providers/nntp/camel-nntp-store.c
index b61bb67..c3b5b22 100644
--- a/camel/providers/nntp/camel-nntp-store.c
+++ b/camel/providers/nntp/camel-nntp-store.c
@@ -58,10 +58,80 @@
 	(G_TYPE_INSTANCE_GET_PRIVATE \
 	((obj), CAMEL_TYPE_NNTP_STORE, CamelNNTPStorePrivate))
 
-static gint camel_nntp_try_authenticate (CamelNNTPStore *store, GError **error);
-
 G_DEFINE_TYPE (CamelNNTPStore, camel_nntp_store, CAMEL_TYPE_DISCO_STORE)
 
+static gint
+camel_nntp_try_authenticate (CamelNNTPStore *store,
+                             GCancellable *cancellable,
+                             GError **error)
+{
+	CamelService *service = (CamelService *) store;
+	CamelSession *session = camel_service_get_session (service);
+	gint ret;
+	gchar *line = NULL;
+	GError *local_error = NULL;
+
+	if (!service->url->user) {
+		g_set_error (
+			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
+			_("Authentication requested but no username provided"));
+		return -1;
+	}
+
+	/* if nessecary, prompt for the password */
+	if (!service->url->passwd) {
+		gchar *prompt, *base;
+	retry:
+		base = camel_session_build_password_prompt (
+			"NNTP", service->url->user, service->url->host);
+		if (line) {
+			gchar *top = g_markup_printf_escaped (
+				_("Cannot authenticate to server: %s"), line);
+
+			prompt = g_strdup_printf("%s\n\n%s", top, base);
+			g_free (top);
+		} else {
+			prompt = base;
+			base = NULL;
+		}
+
+		service->url->passwd =
+			camel_session_get_password (session, service, NULL,
+						    prompt, "password", CAMEL_SESSION_PASSWORD_SECRET | (store->password_reprompt ? CAMEL_SESSION_PASSWORD_REPROMPT : 0), error);
+		g_free (prompt);
+		g_free (base);
+
+		if (!service->url->passwd)
+			return -1;
+
+		store->password_reprompt = FALSE;
+	}
+
+	/* now, send auth info (currently, only authinfo user/pass is supported) */
+	ret = camel_nntp_raw_command(store, cancellable, &local_error, &line, "authinfo user %s", service->url->user);
+	if (ret == NNTP_AUTH_CONTINUE)
+		ret = camel_nntp_raw_command(store, cancellable, &local_error, &line, "authinfo pass %s", service->url->passwd);
+
+	if (ret != NNTP_AUTH_ACCEPTED) {
+		if (ret != -1) {
+			if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ||
+			    g_error_matches (local_error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_UNAVAILABLE)) {
+				g_propagate_error (error, local_error);
+				return ret;
+			}
+
+			/* To force password reprompt */
+			store->password_reprompt = TRUE;
+			g_free (service->url->passwd);
+			service->url->passwd = NULL;
+			goto retry;
+		}
+		return -1;
+	}
+
+	return ret;
+}
+
 static void
 nntp_store_dispose (GObject *object)
 {
@@ -142,7 +212,9 @@ static struct {
 };
 
 static gint
-xover_setup (CamelNNTPStore *store, GError **error)
+xover_setup (CamelNNTPStore *store,
+             GCancellable *cancellable,
+             GError **error)
 {
 	gint ret, i;
 	gchar *line;
@@ -154,7 +226,7 @@ xover_setup (CamelNNTPStore *store, GError **error)
 	if (store->xover || getenv("CAMEL_NNTP_DISABLE_XOVER") != NULL)
 		return 0;
 
-	ret = camel_nntp_raw_command_auth(store, error, &line, "list overview.fmt");
+	ret = camel_nntp_raw_command_auth(store, cancellable, error, &line, "list overview.fmt");
 	if (ret == -1) {
 		return -1;
 	} else if (ret != 215)
@@ -164,7 +236,7 @@ xover_setup (CamelNNTPStore *store, GError **error)
 	last = (struct _xover_header *)&store->xover;
 
 	/* supported command */
-	while ((ret = camel_nntp_stream_line (store->stream, (guchar **)&line, &len, error)) > 0) {
+	while ((ret = camel_nntp_stream_line (store->stream, (guchar **)&line, &len, cancellable, error)) > 0) {
 		p = (guchar *) line;
 		xover = g_malloc0 (sizeof (*xover));
 		last->next = xover;
@@ -205,7 +277,13 @@ enum {
 #endif
 
 static gboolean
-connect_to_server (CamelService *service, const gchar *host, const gchar *serv, gint fallback_port, gint ssl_mode, GError **error)
+connect_to_server (CamelService *service,
+                   const gchar *host,
+                   const gchar *serv,
+                   gint fallback_port,
+                   gint ssl_mode,
+                   GCancellable *cancellable,
+                   GError **error)
 {
 	CamelNNTPStore *store = (CamelNNTPStore *) service;
 	CamelDiscoStore *disco_store = (CamelDiscoStore*) service;
@@ -247,7 +325,9 @@ connect_to_server (CamelService *service, const gchar *host, const gchar *serv,
 		g_free (socks_host);
 	}
 
-	if (camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, host, serv, fallback_port, error) == -1) {
+	if (camel_tcp_stream_connect (
+		CAMEL_TCP_STREAM (tcp_stream), host, serv,
+		fallback_port, cancellable, error) == -1) {
 		g_prefix_error (
 			error, _("Could not connect to %s: "),
 			service->url->host);
@@ -260,7 +340,7 @@ connect_to_server (CamelService *service, const gchar *host, const gchar *serv,
 	g_object_unref (tcp_stream);
 
 	/* Read the greeting, if any. */
-	if (camel_nntp_stream_line (store->stream, &buf, &len, error) == -1) {
+	if (camel_nntp_stream_line (store->stream, &buf, &len, cancellable, error) == -1) {
 		g_prefix_error (
 			error, _("Could not read greeting from %s: "),
 			service->url->host);
@@ -287,15 +367,15 @@ connect_to_server (CamelService *service, const gchar *host, const gchar *serv,
 	/* if we have username, try it here */
 	if (service->url->user != NULL
 	    && service->url->user[0]
-	    && camel_nntp_try_authenticate (store, error) != NNTP_AUTH_ACCEPTED)
+	    && camel_nntp_try_authenticate (store, cancellable, error) != NNTP_AUTH_ACCEPTED)
 		goto fail;
 
 	/* set 'reader' mode & ignore return code, also ping the server, inn goes offline very quickly otherwise */
-	if (camel_nntp_raw_command_auth (store, error, (gchar **) &buf, "mode reader") == -1
-	    || camel_nntp_raw_command_auth (store, error, (gchar **) &buf, "date") == -1)
+	if (camel_nntp_raw_command_auth (store, cancellable, error, (gchar **) &buf, "mode reader") == -1
+	    || camel_nntp_raw_command_auth (store, cancellable, error, (gchar **) &buf, "date") == -1)
 		goto fail;
 
-	if (xover_setup (store, error) == -1)
+	if (xover_setup (store, cancellable, error) == -1)
 		goto fail;
 
 	if (!disco_store->diary) {
@@ -328,7 +408,9 @@ static struct {
 };
 
 static gboolean
-nntp_connect_online (CamelService *service, GError **error)
+nntp_connect_online (CamelService *service,
+                     GCancellable *cancellable,
+                     GError **error)
 {
 	const gchar *ssl_mode;
 	gint mode, i;
@@ -354,11 +436,15 @@ nntp_connect_online (CamelService *service, GError **error)
 		fallback_port = 0;
 	}
 
-	return connect_to_server (service, service->url->host, serv, fallback_port, mode, error);
+	return connect_to_server (
+		service, service->url->host, serv,
+		fallback_port, mode, cancellable, error);
 }
 
 static gboolean
-nntp_connect_offline (CamelService *service, GError **error)
+nntp_connect_offline (CamelService *service,
+                      GCancellable *cancellable,
+                      GError **error)
 {
 	CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (service);
 	CamelDiscoStore *disco_store = (CamelDiscoStore *) nntp_store;
@@ -392,7 +478,10 @@ nntp_connect_offline (CamelService *service, GError **error)
 }
 
 static gboolean
-nntp_disconnect_online (CamelService *service, gboolean clean, GError **error)
+nntp_disconnect_online (CamelService *service,
+                        gboolean clean,
+                        GCancellable *cancellable,
+                        GError **error)
 {
 	CamelNNTPStore *store = CAMEL_NNTP_STORE (service);
 	gchar *line;
@@ -400,7 +489,7 @@ nntp_disconnect_online (CamelService *service, gboolean clean, GError **error)
 	camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
 	if (clean)
-		camel_nntp_raw_command (store, NULL, &line, "quit");
+		camel_nntp_raw_command (store, cancellable, NULL, &line, "quit");
 
 	g_object_unref (store->stream);
 	store->stream = NULL;
@@ -413,7 +502,10 @@ nntp_disconnect_online (CamelService *service, gboolean clean, GError **error)
 }
 
 static gboolean
-nntp_disconnect_offline (CamelService *service, gboolean clean, GError **error)
+nntp_disconnect_offline (CamelService *service,
+                         gboolean clean,
+                         GCancellable *cancellable,
+                         GError **error)
 {
 	CamelDiscoStore *disco = CAMEL_DISCO_STORE (service);
 
@@ -438,22 +530,33 @@ nntp_store_get_name (CamelService *service, gboolean brief)
 extern CamelServiceAuthType camel_nntp_password_authtype;
 
 static GList *
-nntp_store_query_auth_types (CamelService *service, GError **error)
+nntp_store_query_auth_types (CamelService *service,
+                             GCancellable *cancellable,
+                             GError **error)
 {
 	return g_list_append (NULL, &camel_nntp_password_authtype);
 }
 
 static CamelFolder *
-nntp_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, GError **error)
+nntp_get_folder (CamelStore *store,
+                 const gchar *folder_name,
+                 guint32 flags,
+                 GCancellable *cancellable,
+                 GError **error)
 {
 	CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store);
 	CamelFolder *folder;
 
-	camel_service_lock (CAMEL_SERVICE (nntp_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+	camel_service_lock (
+		CAMEL_SERVICE (nntp_store),
+		CAMEL_SERVICE_REC_CONNECT_LOCK);
 
-	folder = camel_nntp_folder_new (store, folder_name, error);
+	folder = camel_nntp_folder_new (
+		store, folder_name, cancellable, error);
 
-	camel_service_unlock (CAMEL_SERVICE (nntp_store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+	camel_service_unlock (
+		CAMEL_SERVICE (nntp_store),
+		CAMEL_SERVICE_REC_CONNECT_LOCK);
 
 	return folder;
 }
@@ -613,7 +716,11 @@ nntp_store_info_update (CamelNNTPStore *store, gchar *line)
 }
 
 static CamelFolderInfo *
-nntp_store_get_subscribed_folder_info (CamelNNTPStore *store, const gchar *top, guint flags, GError **error)
+nntp_store_get_subscribed_folder_info (CamelNNTPStore *store,
+                                       const gchar *top,
+                                       guint flags,
+                                       GCancellable *cancellable,
+                                       GError **error)
 {
 	gint i;
 	CamelStoreInfo *si;
@@ -634,12 +741,15 @@ nntp_store_get_subscribed_folder_info (CamelNNTPStore *store, const gchar *top,
 				CamelNNTPFolder *folder;
 				gchar *line;
 
-				folder = (CamelNNTPFolder *)camel_store_get_folder ((CamelStore *)store, si->path, 0, NULL);
+				folder = (CamelNNTPFolder *)
+					camel_store_get_folder (
+					(CamelStore *)store, si->path,
+					0, cancellable, NULL);
 				if (folder) {
 					CamelFolderChangeInfo *changes = NULL;
 
 					camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
-					camel_nntp_command (store, NULL, folder, &line, NULL);
+					camel_nntp_command (store, cancellable, NULL, folder, &line, NULL);
 					if (camel_folder_change_info_changed (folder->changes)) {
 						changes = folder->changes;
 						folder->changes = camel_folder_change_info_new ();
@@ -831,12 +941,29 @@ nntp_store_get_cached_folder_info (CamelNNTPStore *store, const gchar *orig_top,
 	return first;
 }
 
+static void
+store_info_remove (gpointer key, gpointer value, gpointer data)
+{
+	CamelStoreSummary *summary = data;
+	CamelStoreInfo *si = value;
+
+	camel_store_summary_remove (summary, si);
+}
+
+static gint
+store_info_sort (gconstpointer a, gconstpointer b)
+{
+	return strcmp ((*(CamelNNTPStoreInfo**) a)->full_name, (*(CamelNNTPStoreInfo**) b)->full_name);
+}
+
 /* retrieves the date from the NNTP server */
 static gboolean
-nntp_get_date (CamelNNTPStore *nntp_store, GError **error)
+nntp_get_date (CamelNNTPStore *nntp_store,
+               GCancellable *cancellable,
+               GError **error)
 {
 	guchar *line;
-	gint ret = camel_nntp_command(nntp_store, error, NULL, (gchar **)&line, "date");
+	gint ret = camel_nntp_command(nntp_store, cancellable, error, NULL, (gchar **)&line, "date");
 	gchar *ptr;
 
 	nntp_store->summary->last_newslist[0] = 0;
@@ -854,23 +981,13 @@ nntp_get_date (CamelNNTPStore *nntp_store, GError **error)
 	return FALSE;
 }
 
-static void
-store_info_remove (gpointer key, gpointer value, gpointer data)
-{
-	CamelStoreSummary *summary = data;
-	CamelStoreInfo *si = value;
-
-	camel_store_summary_remove (summary, si);
-}
-
-static gint
-store_info_sort (gconstpointer a, gconstpointer b)
-{
-	return strcmp ((*(CamelNNTPStoreInfo**) a)->full_name, (*(CamelNNTPStoreInfo**) b)->full_name);
-}
-
 static CamelFolderInfo *
-nntp_store_get_folder_info_all (CamelNNTPStore *nntp_store, const gchar *top, guint32 flags, gboolean online, GError **error)
+nntp_store_get_folder_info_all (CamelNNTPStore *nntp_store,
+                                const gchar *top,
+                                guint32 flags,
+                                gboolean online,
+                                GCancellable *cancellable,
+                                GError **error)
 {
 	CamelNNTPStoreSummary *summary = nntp_store->summary;
 	CamelNNTPStoreInfo *si;
@@ -894,10 +1011,10 @@ nntp_store_get_folder_info_all (CamelNNTPStore *nntp_store, const gchar *top, gu
 			date[13] = '\0';
 
 			/* Some servers don't support date (!), so fallback if they dont */
-			if (!nntp_get_date (nntp_store, NULL))
+			if (!nntp_get_date (nntp_store, cancellable, NULL))
 				goto do_complete_list_nodate;
 
-			ret = camel_nntp_command (nntp_store, error, NULL, (gchar **) &line, "newgroups %s", date);
+			ret = camel_nntp_command (nntp_store, cancellable, error, NULL, (gchar **) &line, "newgroups %s", date);
 			if (ret == -1)
 				goto error;
 			else if (ret != 231) {
@@ -906,7 +1023,7 @@ nntp_store_get_folder_info_all (CamelNNTPStore *nntp_store, const gchar *top, gu
 				goto do_complete_list;
 			}
 
-			while ((ret = camel_nntp_stream_line (nntp_store->stream, &line, &len, error)) > 0)
+			while ((ret = camel_nntp_stream_line (nntp_store->stream, &line, &len, cancellable, error)) > 0)
 				nntp_store_info_update (nntp_store, (gchar *) line);
 		} else {
 			GHashTable *all;
@@ -915,9 +1032,9 @@ nntp_store_get_folder_info_all (CamelNNTPStore *nntp_store, const gchar *top, gu
 		do_complete_list:
 			/* seems we do need a complete list */
 			/* at first, we do a DATE to find out the last load occasion */
-			nntp_get_date (nntp_store, NULL);
+			nntp_get_date (nntp_store, cancellable, NULL);
 		do_complete_list_nodate:
-			ret = camel_nntp_command (nntp_store, error, NULL, (gchar **)&line, "list");
+			ret = camel_nntp_command (nntp_store, cancellable, error, NULL, (gchar **)&line, "list");
 			if (ret == -1)
 				goto error;
 			else if (ret != 215) {
@@ -932,7 +1049,7 @@ nntp_store_get_folder_info_all (CamelNNTPStore *nntp_store, const gchar *top, gu
 			for (i = 0; (si = (CamelNNTPStoreInfo *)camel_store_summary_index ((CamelStoreSummary *)nntp_store->summary, i)); i++)
 				g_hash_table_insert (all, si->info.path, si);
 
-			while ((ret = camel_nntp_stream_line (nntp_store->stream, &line, &len, error)) > 0) {
+			while ((ret = camel_nntp_stream_line (nntp_store->stream, &line, &len, cancellable, error)) > 0) {
 				si = nntp_store_info_update (nntp_store, (gchar *) line);
 				g_hash_table_remove (all, si->info.path);
 			}
@@ -957,7 +1074,12 @@ nntp_store_get_folder_info_all (CamelNNTPStore *nntp_store, const gchar *top, gu
 }
 
 static CamelFolderInfo *
-nntp_get_folder_info (CamelStore *store, const gchar *top, guint32 flags, gboolean online, GError **error)
+nntp_get_folder_info (CamelStore *store,
+                      const gchar *top,
+                      guint32 flags,
+                      gboolean online,
+                      GCancellable *cancellable,
+                      GError **error)
 {
 	CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store);
 	CamelFolderInfo *first = NULL;
@@ -970,23 +1092,34 @@ nntp_get_folder_info (CamelStore *store, const gchar *top, guint32 flags, gboole
 		top?top:""));
 
 	if (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)
-		first = nntp_store_get_subscribed_folder_info (nntp_store, top, flags, error);
+		first = nntp_store_get_subscribed_folder_info (
+			nntp_store, top, flags, cancellable, error);
 	else
-		first = nntp_store_get_folder_info_all (nntp_store, top, flags, online, error);
+		first = nntp_store_get_folder_info_all (nntp_store, top, flags, online, cancellable, error);
 
 	return first;
 }
 
 static CamelFolderInfo *
-nntp_get_folder_info_online (CamelStore *store, const gchar *top, guint32 flags, GError **error)
+nntp_get_folder_info_online (CamelStore *store,
+                             const gchar *top,
+                             guint32 flags,
+                             GCancellable *cancellable,
+                             GError **error)
 {
-	return nntp_get_folder_info (store, top, flags, TRUE, error);
+	return nntp_get_folder_info (
+		store, top, flags, TRUE, cancellable, error);
 }
 
 static CamelFolderInfo *
-nntp_get_folder_info_offline (CamelStore *store, const gchar *top, guint32 flags, GError **error)
+nntp_get_folder_info_offline (CamelStore *store,
+                              const gchar *top,
+                              guint32 flags,
+                              GCancellable *cancellable,
+                              GError **error)
 {
-	return nntp_get_folder_info (store, top, flags, FALSE, error);
+	return nntp_get_folder_info (
+		store, top, flags, FALSE, cancellable, error);
 }
 
 static gboolean
@@ -1006,8 +1139,10 @@ nntp_store_folder_is_subscribed (CamelStore *store, const gchar *folder_name)
 }
 
 static gboolean
-nntp_store_subscribe_folder (CamelStore *store, const gchar *folder_name,
-			     GError **error)
+nntp_store_subscribe_folder (CamelStore *store,
+                             const gchar *folder_name,
+                             GCancellable *cancellable,
+                             GError **error)
 {
 	CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store);
 	CamelStoreInfo *si;
@@ -1045,8 +1180,10 @@ nntp_store_subscribe_folder (CamelStore *store, const gchar *folder_name,
 }
 
 static gboolean
-nntp_store_unsubscribe_folder (CamelStore *store, const gchar *folder_name,
-			       GError **error)
+nntp_store_unsubscribe_folder (CamelStore *store,
+                               const gchar *folder_name,
+                               GCancellable *cancellable,
+                               GError **error)
 {
 	CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store);
 	CamelFolderInfo *fi;
@@ -1085,8 +1222,11 @@ nntp_store_unsubscribe_folder (CamelStore *store, const gchar *folder_name,
 /* stubs for various folder operations we're not implementing */
 
 static CamelFolderInfo *
-nntp_create_folder (CamelStore *store, const gchar *parent_name,
-                    const gchar *folder_name, GError **error)
+nntp_create_folder (CamelStore *store,
+                    const gchar *parent_name,
+                    const gchar *folder_name,
+                    GCancellable *cancellable,
+                    GError **error)
 {
 	g_set_error (
 		error, CAMEL_FOLDER_ERROR,
@@ -1098,7 +1238,11 @@ nntp_create_folder (CamelStore *store, const gchar *parent_name,
 }
 
 static gboolean
-nntp_rename_folder (CamelStore *store, const gchar *old_name, const gchar *new_name_in, GError **error)
+nntp_rename_folder (CamelStore *store,
+                    const gchar *old_name,
+                    const gchar *new_name_in,
+                    GCancellable *cancellable,
+                    GError **error)
 {
 	g_set_error (
 		error, CAMEL_FOLDER_ERROR,
@@ -1109,9 +1253,12 @@ nntp_rename_folder (CamelStore *store, const gchar *old_name, const gchar *new_n
 }
 
 static gboolean
-nntp_delete_folder (CamelStore *store, const gchar *folder_name, GError **error)
+nntp_delete_folder (CamelStore *store,
+                    const gchar *folder_name,
+                    GCancellable *cancellable,
+                    GError **error)
 {
-	nntp_store_unsubscribe_folder (store, folder_name, NULL);
+	nntp_store_unsubscribe_folder (store, folder_name, cancellable, NULL);
 
 	g_set_error (
 		error, CAMEL_FOLDER_ERROR,
@@ -1242,79 +1389,14 @@ camel_nntp_store_init (CamelNNTPStore *nntp_store)
 	nntp_store->priv = CAMEL_NNTP_STORE_GET_PRIVATE (nntp_store);
 }
 
-static gint
-camel_nntp_try_authenticate (CamelNNTPStore *store, GError **error)
-{
-	CamelService *service = (CamelService *) store;
-	CamelSession *session = camel_service_get_session (service);
-	gint ret;
-	gchar *line = NULL;
-	GError *local_error = NULL;
-
-	if (!service->url->user) {
-		g_set_error (
-			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
-			_("Authentication requested but no username provided"));
-		return -1;
-	}
-
-	/* if nessecary, prompt for the password */
-	if (!service->url->passwd) {
-		gchar *prompt, *base;
-	retry:
-		base = camel_session_build_password_prompt (
-			"NNTP", service->url->user, service->url->host);
-		if (line) {
-			gchar *top = g_markup_printf_escaped (
-				_("Cannot authenticate to server: %s"), line);
-
-			prompt = g_strdup_printf("%s\n\n%s", top, base);
-			g_free (top);
-		} else {
-			prompt = base;
-			base = NULL;
-		}
-
-		service->url->passwd =
-			camel_session_get_password (session, service, NULL,
-						    prompt, "password", CAMEL_SESSION_PASSWORD_SECRET | (store->password_reprompt ? CAMEL_SESSION_PASSWORD_REPROMPT : 0), error);
-		g_free (prompt);
-		g_free (base);
-
-		if (!service->url->passwd)
-			return -1;
-
-		store->password_reprompt = FALSE;
-	}
-
-	/* now, send auth info (currently, only authinfo user/pass is supported) */
-	ret = camel_nntp_raw_command(store, &local_error, &line, "authinfo user %s", service->url->user);
-	if (ret == NNTP_AUTH_CONTINUE)
-		ret = camel_nntp_raw_command(store, &local_error, &line, "authinfo pass %s", service->url->passwd);
-
-	if (ret != NNTP_AUTH_ACCEPTED) {
-		if (ret != -1) {
-			if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ||
-			    g_error_matches (local_error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_UNAVAILABLE)) {
-				g_propagate_error (error, local_error);
-				return ret;
-			}
-
-			/* To force password reprompt */
-			store->password_reprompt = TRUE;
-			g_free (service->url->passwd);
-			service->url->passwd = NULL;
-			goto retry;
-		}
-		return -1;
-	}
-
-	return ret;
-}
-
 /* Enter owning lock */
 gint
-camel_nntp_raw_commandv (CamelNNTPStore *store, GError **error, gchar **line, const gchar *fmt, va_list ap)
+camel_nntp_raw_commandv (CamelNNTPStore *store,
+                         GCancellable *cancellable,
+                         GError **error,
+                         gchar **line,
+                         const gchar *fmt,
+                         va_list ap)
 {
 	GByteArray *byte_array;
 	const guchar *p, *ps;
@@ -1334,12 +1416,12 @@ camel_nntp_raw_commandv (CamelNNTPStore *store, GError **error, gchar **line, co
 		switch (c) {
 		case '%':
 			c = *p++;
-			camel_stream_write ((CamelStream *) store->mem, (const gchar *) ps, p - ps - (c == '%' ? 1 : 2), NULL);
+			camel_stream_write ((CamelStream *) store->mem, (const gchar *) ps, p - ps - (c == '%' ? 1 : 2), NULL, NULL);
 			ps = p;
 			switch (c) {
 			case 's':
 				s = va_arg (ap, gchar *);
-				camel_stream_write ((CamelStream *)store->mem, s, strlen (s), NULL);
+				camel_stream_write ((CamelStream *)store->mem, s, strlen (s), NULL, NULL);
 				break;
 			case 'd':
 				d = va_arg (ap, gint);
@@ -1368,19 +1450,19 @@ camel_nntp_raw_commandv (CamelNNTPStore *store, GError **error, gchar **line, co
 		}
 	}
 
-	camel_stream_write ((CamelStream *) store->mem, (const gchar *) ps, p-ps-1, NULL);
-	camel_stream_write ((CamelStream *) store->mem, "\r\n", 2, NULL);
+	camel_stream_write ((CamelStream *) store->mem, (const gchar *) ps, p-ps-1, NULL, NULL);
+	camel_stream_write ((CamelStream *) store->mem, "\r\n", 2, NULL, NULL);
 
 	byte_array = camel_stream_mem_get_byte_array (store->mem);
 
-	if (camel_stream_write ((CamelStream *) store->stream, (const gchar *) byte_array->data, byte_array->len, error) == -1)
+	if (camel_stream_write ((CamelStream *) store->stream, (const gchar *) byte_array->data, byte_array->len, cancellable, error) == -1)
 		goto ioerror;
 
 	/* FIXME: hack */
 	camel_stream_reset ((CamelStream *) store->mem, NULL);
 	g_byte_array_set_size (byte_array, 0);
 
-	if (camel_nntp_stream_line (store->stream, (guchar **) line, &u, error) == -1)
+	if (camel_nntp_stream_line (store->stream, (guchar **) line, &u, cancellable, error) == -1)
 		goto ioerror;
 
 	u = strtoul (*line, NULL, 10);
@@ -1397,13 +1479,18 @@ ioerror:
 }
 
 gint
-camel_nntp_raw_command (CamelNNTPStore *store, GError **error, gchar **line, const gchar *fmt, ...)
+camel_nntp_raw_command (CamelNNTPStore *store,
+                        GCancellable *cancellable,
+                        GError **error,
+                        gchar **line,
+                        const gchar *fmt,
+                        ...)
 {
 	gint ret;
 	va_list ap;
 
 	va_start (ap, fmt);
-	ret = camel_nntp_raw_commandv (store, error, line, fmt, ap);
+	ret = camel_nntp_raw_commandv (store, cancellable, error, line, fmt, ap);
 	va_end (ap);
 
 	return ret;
@@ -1411,7 +1498,12 @@ camel_nntp_raw_command (CamelNNTPStore *store, GError **error, gchar **line, con
 
 /* use this where you also need auth to be handled, i.e. most cases where you'd try raw command */
 gint
-camel_nntp_raw_command_auth (CamelNNTPStore *store, GError **error, gchar **line, const gchar *fmt, ...)
+camel_nntp_raw_command_auth (CamelNNTPStore *store,
+                             GCancellable *cancellable,
+                             GError **error,
+                             gchar **line,
+                             const gchar *fmt,
+                             ...)
 {
 	gint ret, retry, go;
 	va_list ap;
@@ -1423,11 +1515,11 @@ camel_nntp_raw_command_auth (CamelNNTPStore *store, GError **error, gchar **line
 		retry++;
 
 		va_start (ap, fmt);
-		ret = camel_nntp_raw_commandv (store, error, line, fmt, ap);
+		ret = camel_nntp_raw_commandv (store, cancellable, error, line, fmt, ap);
 		va_end (ap);
 
 		if (ret == NNTP_AUTH_REQUIRED) {
-			if (camel_nntp_try_authenticate (store, error) != NNTP_AUTH_ACCEPTED)
+			if (camel_nntp_try_authenticate (store, cancellable, error) != NNTP_AUTH_ACCEPTED)
 				return -1;
 			go = TRUE;
 		}
@@ -1437,7 +1529,13 @@ camel_nntp_raw_command_auth (CamelNNTPStore *store, GError **error, gchar **line
 }
 
 gint
-camel_nntp_command (CamelNNTPStore *store, GError **error, CamelNNTPFolder *folder, gchar **line, const gchar *fmt, ...)
+camel_nntp_command (CamelNNTPStore *store,
+                    GCancellable *cancellable,
+                    GError **error,
+                    CamelNNTPFolder *folder,
+                    gchar **line,
+                    const gchar *fmt,
+                    ...)
 {
 	const gchar *full_name = NULL;
 	const guchar *p;
@@ -1468,18 +1566,18 @@ camel_nntp_command (CamelNNTPStore *store, GError **error, CamelNNTPFolder *fold
 		/* Check for unprocessed data, !*/
 		if (store->stream->mode == CAMEL_NNTP_STREAM_DATA) {
 			g_warning("Unprocessed data left in stream, flushing");
-			while (camel_nntp_stream_getd (store->stream, (guchar **)&p, &u) > 0)
+			while (camel_nntp_stream_getd (store->stream, (guchar **)&p, &u, cancellable, error) > 0)
 				;
 		}
 		camel_nntp_stream_set_mode (store->stream, CAMEL_NNTP_STREAM_LINE);
 
 		if (folder != NULL
 		    && (store->current_folder == NULL || strcmp (store->current_folder, full_name) != 0)) {
-			ret = camel_nntp_raw_command_auth(store, &local_error, line, "group %s", full_name);
+			ret = camel_nntp_raw_command_auth(store, cancellable, &local_error, line, "group %s", full_name);
 			if (ret == 211) {
 				g_free (store->current_folder);
 				store->current_folder = g_strdup (full_name);
-				if (camel_nntp_folder_selected (folder, *line, &local_error) < 0) {
+				if (camel_nntp_folder_selected (folder, *line, NULL, &local_error) < 0) {
 					ret = -1;
 					goto error;
 				}
@@ -1493,12 +1591,12 @@ camel_nntp_command (CamelNNTPStore *store, GError **error, CamelNNTPFolder *fold
 			return 0;
 
 		va_start (ap, fmt);
-		ret = camel_nntp_raw_commandv (store, &local_error, line, fmt, ap);
+		ret = camel_nntp_raw_commandv (store, cancellable, &local_error, line, fmt, ap);
 		va_end (ap);
 	error:
 		switch (ret) {
 		case NNTP_AUTH_REQUIRED:
-			if (camel_nntp_try_authenticate (store, error) != NNTP_AUTH_ACCEPTED)
+			if (camel_nntp_try_authenticate (store, cancellable, error) != NNTP_AUTH_ACCEPTED)
 				return -1;
 			retry--;
 			ret = -1;
diff --git a/camel/providers/nntp/camel-nntp-store.h b/camel/providers/nntp/camel-nntp-store.h
index 1e968c2..074789a 100644
--- a/camel/providers/nntp/camel-nntp-store.h
+++ b/camel/providers/nntp/camel-nntp-store.h
@@ -109,10 +109,10 @@ struct _CamelNNTPStoreClass {
 
 GType camel_nntp_store_get_type (void);
 
-gint camel_nntp_raw_commandv (CamelNNTPStore *store, struct _GError **error, gchar **line, const gchar *fmt, va_list ap);
-gint camel_nntp_raw_command (CamelNNTPStore *store, struct _GError **error, gchar **line, const gchar *fmt, ...);
-gint camel_nntp_raw_command_auth (CamelNNTPStore *store, struct _GError **error, gchar **line, const gchar *fmt, ...);
-gint camel_nntp_command (CamelNNTPStore *store, struct _GError **error, struct _CamelNNTPFolder *folder, gchar **line, const gchar *fmt, ...);
+gint camel_nntp_raw_commandv (CamelNNTPStore *store, GCancellable *cancellable, GError **error, gchar **line, const gchar *fmt, va_list ap);
+gint camel_nntp_raw_command (CamelNNTPStore *store, GCancellable *cancellable, GError **error, gchar **line, const gchar *fmt, ...);
+gint camel_nntp_raw_command_auth (CamelNNTPStore *store, GCancellable *cancellable, GError **error, gchar **line, const gchar *fmt, ...);
+gint camel_nntp_command (CamelNNTPStore *store, GCancellable *cancellable, GError **error, struct _CamelNNTPFolder *folder, gchar **line, const gchar *fmt, ...);
 
 G_END_DECLS
 
diff --git a/camel/providers/nntp/camel-nntp-stream.c b/camel/providers/nntp/camel-nntp-stream.c
index 33d6605..bce5b68 100644
--- a/camel/providers/nntp/camel-nntp-stream.c
+++ b/camel/providers/nntp/camel-nntp-stream.c
@@ -70,6 +70,7 @@ nntp_stream_finalize (GObject *object)
 
 static gint
 nntp_stream_fill (CamelNNTPStream *is,
+                  GCancellable *cancellable,
                   GError **error)
 {
 	gint left = 0;
@@ -81,7 +82,8 @@ nntp_stream_fill (CamelNNTPStream *is,
 		is->ptr = is->buf;
 		left = camel_stream_read (
 			is->source, (gchar *) is->end,
-			CAMEL_NNTP_STREAM_SIZE - (is->end - is->buf), error);
+			CAMEL_NNTP_STREAM_SIZE - (is->end - is->buf),
+			cancellable, error);
 		if (left > 0) {
 			is->end += left;
 			is->end[0] = '\n';
@@ -106,6 +108,7 @@ static gssize
 nntp_stream_read (CamelStream *stream,
                   gchar *buffer,
                   gsize n,
+                  GCancellable *cancellable,
                   GError **error)
 {
 	CamelNNTPStream *is = (CamelNNTPStream *)stream;
@@ -129,7 +132,7 @@ nntp_stream_read (CamelStream *stream,
 	case 0:		/* start of line, always read at least 3 chars */
 		while (e - p < 3) {
 			is->ptr = p;
-			if (nntp_stream_fill (is, error) == -1)
+			if (nntp_stream_fill (is, cancellable, error) == -1)
 				return -1;
 			p = is->ptr;
 			e = is->end;
@@ -153,7 +156,7 @@ nntp_stream_read (CamelStream *stream,
 				/* end of input sentinal check */
 				if (p > e) {
 					is->ptr = e;
-					if (nntp_stream_fill (is, error) == -1)
+					if (nntp_stream_fill (is, cancellable, error) == -1)
 						return -1;
 					p = is->ptr;
 					e = is->end;
@@ -181,15 +184,17 @@ static gssize
 nntp_stream_write (CamelStream *stream,
                    const gchar *buffer,
                    gsize n,
+                   GCancellable *cancellable,
                    GError **error)
 {
 	CamelNNTPStream *is = (CamelNNTPStream *)stream;
 
-	return camel_stream_write (is->source, buffer, n, error);
+	return camel_stream_write (is->source, buffer, n, cancellable, error);
 }
 
 static gint
 nntp_stream_close (CamelStream *stream,
+                   GCancellable *cancellable,
                    GError **error)
 {
 	/* nop? */
@@ -198,6 +203,7 @@ nntp_stream_close (CamelStream *stream,
 
 static gint
 nntp_stream_flush (CamelStream *stream,
+                   GCancellable *cancellable,
                    GError **error)
 {
 	/* nop? */
@@ -278,6 +284,7 @@ gint
 camel_nntp_stream_line (CamelNNTPStream *is,
                         guchar **data,
                         guint *len,
+                        GCancellable *cancellable,
                         GError **error)
 {
 	register guchar c, *p, *o, *oe;
@@ -300,7 +307,7 @@ camel_nntp_stream_line (CamelNNTPStream *is,
 		/* need at least 3 chars in buffer */
 		while (e-p < 3) {
 			is->ptr = p;
-			if (nntp_stream_fill (is, error) == -1)
+			if (nntp_stream_fill (is, cancellable, error) == -1)
 				return -1;
 			p = is->ptr;
 			e = is->end;
@@ -330,7 +337,7 @@ camel_nntp_stream_line (CamelNNTPStream *is,
 				/* sentinal? */
 				if (p> e) {
 					is->ptr = e;
-					if (nntp_stream_fill (is, error) == -1)
+					if (nntp_stream_fill (is, cancellable, error) == -1)
 						return -1;
 					p = is->ptr;
 					e = is->end;
@@ -363,7 +370,9 @@ camel_nntp_stream_line (CamelNNTPStream *is,
 gint
 camel_nntp_stream_gets (CamelNNTPStream *is,
                         guchar **start,
-                        guint *len)
+                        guint *len,
+                        GCancellable *cancellable,
+                        GError **error)
 {
 	gint max;
 	guchar *end;
@@ -372,7 +381,7 @@ camel_nntp_stream_gets (CamelNNTPStream *is,
 
 	max = is->end - is->ptr;
 	if (max == 0) {
-		max = nntp_stream_fill (is, NULL);
+		max = nntp_stream_fill (is, cancellable, error);
 		if (max <= 0)
 			return max;
 	}
@@ -401,7 +410,9 @@ camel_nntp_stream_set_mode (CamelNNTPStream *is,
 gint
 camel_nntp_stream_getd (CamelNNTPStream *is,
                         guchar **start,
-                        guint *len)
+                        guint *len,
+                        GCancellable *cancellable,
+                        GError **error)
 {
 	guchar *p, *e, *s;
 	gint state;
@@ -422,7 +433,7 @@ camel_nntp_stream_getd (CamelNNTPStream *is,
 
 	while (e - p < 3) {
 		is->ptr = p;
-		if (nntp_stream_fill (is, NULL) == -1)
+		if (nntp_stream_fill (is, cancellable, error) == -1)
 			return -1;
 		p = is->ptr;
 		e = is->end;
diff --git a/camel/providers/nntp/camel-nntp-stream.h b/camel/providers/nntp/camel-nntp-stream.h
index 6675243..66f22e3 100644
--- a/camel/providers/nntp/camel-nntp-stream.h
+++ b/camel/providers/nntp/camel-nntp-stream.h
@@ -78,13 +78,18 @@ void		camel_nntp_stream_set_mode	(CamelNNTPStream *is,
 gint		camel_nntp_stream_line		(CamelNNTPStream *is,
 						 guchar **data,
 						 guint *len,
+						 GCancellable *cancellable,
 						 GError **error);
 gint		camel_nntp_stream_gets		(CamelNNTPStream *is,
 						 guchar **start,
-						 guint *len);
+						 guint *len,
+						 GCancellable *cancellable,
+						 GError **error);
 gint		camel_nntp_stream_getd		(CamelNNTPStream *is,
 						 guchar **start,
-						 guint *len);
+						 guint *len,
+						 GCancellable *cancellable,
+						 GError **error);
 
 G_END_DECLS
 
diff --git a/camel/providers/nntp/camel-nntp-summary.c b/camel/providers/nntp/camel-nntp-summary.c
index b0df90d..1076171 100644
--- a/camel/providers/nntp/camel-nntp-summary.c
+++ b/camel/providers/nntp/camel-nntp-summary.c
@@ -220,7 +220,13 @@ summary_header_save (CamelFolderSummary *s, FILE *out)
 
 /* Note: This will be called from camel_nntp_command, so only use camel_nntp_raw_command */
 static gint
-add_range_xover (CamelNNTPSummary *cns, CamelNNTPStore *store, guint high, guint low, CamelFolderChangeInfo *changes, GError **error)
+add_range_xover (CamelNNTPSummary *cns,
+                 CamelNNTPStore *store,
+                 guint high,
+                 guint low,
+                 CamelFolderChangeInfo *changes,
+                 GCancellable *cancellable,
+                 GError **error)
 {
 	CamelFolderSummary *s;
 	CamelMessageInfoBase *mi;
@@ -235,14 +241,16 @@ add_range_xover (CamelNNTPSummary *cns, CamelNNTPStore *store, guint high, guint
 	s = (CamelFolderSummary *)cns;
 	summary_table = camel_folder_summary_get_hashtable (s);
 
-	camel_operation_start (NULL, _("%s: Scanning new messages"), ((CamelService *)store)->url->host);
+	camel_operation_start (
+		cancellable, _("%s: Scanning new messages"),
+		((CamelService *)store)->url->host);
 
-	ret = camel_nntp_raw_command_auth (store, error, &line, "over %r", low, high);
+	ret = camel_nntp_raw_command_auth (store, cancellable, error, &line, "over %r", low, high);
 	if (ret != 224)
-		ret = camel_nntp_raw_command_auth (store, error, &line, "xover %r", low, high);
+		ret = camel_nntp_raw_command_auth (store, cancellable, error, &line, "xover %r", low, high);
 
 	if (ret != 224) {
-		camel_operation_end (NULL);
+		camel_operation_end (cancellable);
 		if (ret != -1)
 			g_set_error (
 				error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
@@ -252,8 +260,8 @@ add_range_xover (CamelNNTPSummary *cns, CamelNNTPStore *store, guint high, guint
 
 	count = 0;
 	total = high-low+1;
-	while ((ret = camel_nntp_stream_line (store->stream, (guchar **)&line, &len, error)) > 0) {
-		camel_operation_progress (NULL, (count * 100) / total);
+	while ((ret = camel_nntp_stream_line (store->stream, (guchar **)&line, &len, cancellable, error)) > 0) {
+		camel_operation_progress (cancellable, (count * 100) / total);
 		count++;
 		n = strtoul (line, &tab, 10);
 		if (*tab != '\t')
@@ -295,7 +303,8 @@ add_range_xover (CamelNNTPSummary *cns, CamelNNTPStore *store, guint high, guint
 		/* truncated line? ignore? */
 		if (xover == NULL) {
 			if (!GPOINTER_TO_INT (g_hash_table_lookup (summary_table, cns->priv->uid))) {
-				mi = (CamelMessageInfoBase *)camel_folder_summary_add_from_header (s, headers);
+				mi = (CamelMessageInfoBase *)
+					camel_folder_summary_add_from_header (s, headers);
 				if (mi) {
 					mi->size = size;
 					cns->high = n;
@@ -312,7 +321,7 @@ add_range_xover (CamelNNTPSummary *cns, CamelNNTPStore *store, guint high, guint
 		camel_header_raw_clear (&headers);
 	}
 
-	camel_operation_end (NULL);
+	camel_operation_end (cancellable);
 
 	camel_folder_summary_free_hashtable (summary_table);
 
@@ -321,7 +330,13 @@ add_range_xover (CamelNNTPSummary *cns, CamelNNTPStore *store, guint high, guint
 
 /* Note: This will be called from camel_nntp_command, so only use camel_nntp_raw_command */
 static gint
-add_range_head (CamelNNTPSummary *cns, CamelNNTPStore *store, guint high, guint low, CamelFolderChangeInfo *changes, GError **error)
+add_range_head (CamelNNTPSummary *cns,
+                CamelNNTPStore *store,
+                guint high,
+                guint low,
+                CamelFolderChangeInfo *changes,
+                GCancellable *cancellable,
+                GError **error)
 {
 	CamelFolderSummary *s;
 	gint ret = -1;
@@ -337,14 +352,16 @@ add_range_head (CamelNNTPSummary *cns, CamelNNTPStore *store, guint high, guint
 
 	mp = camel_mime_parser_new ();
 
-	camel_operation_start (NULL, _("%s: Scanning new messages"), ((CamelService *)store)->url->host);
+	camel_operation_start (
+		cancellable, _("%s: Scanning new messages"),
+		((CamelService *)store)->url->host);
 
 	count = 0;
 	total = high-low+1;
 	for (i=low;i<high+1;i++) {
-		camel_operation_progress (NULL, (count * 100) / total);
+		camel_operation_progress (cancellable, (count * 100) / total);
 		count++;
-		ret = camel_nntp_raw_command_auth (store, error, &line, "head %u", i);
+		ret = camel_nntp_raw_command_auth (store, cancellable, error, &line, "head %u", i);
 		/* unknown article, ignore */
 		if (ret == 423)
 			continue;
@@ -409,7 +426,7 @@ ioerror:
 	}
 	g_object_unref (mp);
 
-	camel_operation_end (NULL);
+	camel_operation_end (cancellable);
 
 	camel_folder_summary_free_hashtable (summary_table);
 
@@ -419,7 +436,12 @@ ioerror:
 /* Assumes we have the stream */
 /* Note: This will be called from camel_nntp_command, so only use camel_nntp_raw_command */
 gint
-camel_nntp_summary_check (CamelNNTPSummary *cns, CamelNNTPStore *store, gchar *line, CamelFolderChangeInfo *changes, GError **error)
+camel_nntp_summary_check (CamelNNTPSummary *cns,
+                          CamelNNTPStore *store,
+                          gchar *line,
+                          CamelFolderChangeInfo *changes,
+                          GCancellable *cancellable,
+                          GError **error)
 {
 	CamelFolderSummary *s;
 	gint ret = 0, i;
@@ -497,11 +519,14 @@ camel_nntp_summary_check (CamelNNTPSummary *cns, CamelNNTPStore *store, gchar *l
 		if (cns->high < f)
 			cns->high = f-1;
 
-		if (store->xover) {
-			ret = add_range_xover (cns, store, l, cns->high+1, changes, error);
-		} else {
-			ret = add_range_head (cns, store, l, cns->high+1, changes, error);
-		}
+		if (store->xover)
+			ret = add_range_xover (
+				cns, store, l, cns->high+1,
+				changes, cancellable, error);
+		else
+			ret = add_range_head (
+				cns, store, l, cns->high+1,
+				changes, cancellable, error);
 	}
 
 	/* TODO: not from here */
diff --git a/camel/providers/nntp/camel-nntp-summary.h b/camel/providers/nntp/camel-nntp-summary.h
index 39c3f2c..98236e0 100644
--- a/camel/providers/nntp/camel-nntp-summary.h
+++ b/camel/providers/nntp/camel-nntp-summary.h
@@ -63,10 +63,16 @@ struct _CamelNNTPSummaryClass {
 	CamelFolderSummaryClass parent_class;
 };
 
-GType	camel_nntp_summary_get_type	(void);
-CamelNNTPSummary *camel_nntp_summary_new (struct _CamelFolder *folder, const gchar *path);
-
-gint camel_nntp_summary_check (CamelNNTPSummary *cns, struct _CamelNNTPStore *store, gchar *line, struct _CamelFolderChangeInfo *changes, struct _GError **error);
+GType		camel_nntp_summary_get_type	(void);
+CamelNNTPSummary *
+		camel_nntp_summary_new		(CamelFolder *folder,
+						 const gchar *path);
+gint		camel_nntp_summary_check	(CamelNNTPSummary *cns,
+						 struct _CamelNNTPStore *store,
+						 gchar *line,
+						 CamelFolderChangeInfo *changes,
+						 GCancellable *cancellable,
+						 GError **error);
 
 G_END_DECLS
 
diff --git a/camel/providers/pop3/camel-pop3-engine.c b/camel/providers/pop3/camel-pop3-engine.c
index e8eec31..2fe371c 100644
--- a/camel/providers/pop3/camel-pop3-engine.c
+++ b/camel/providers/pop3/camel-pop3-engine.c
@@ -252,7 +252,7 @@ engine_command_queue (CamelPOP3Engine *pe, CamelPOP3Command *pc)
 	}
 
 	/* ??? */
-	if (camel_stream_write ((CamelStream *)pe->stream, pc->data, strlen (pc->data), NULL) == -1) {
+	if (camel_stream_write ((CamelStream *)pe->stream, pc->data, strlen (pc->data), NULL, NULL) == -1) {
 		camel_dlist_addtail (&pe->queue, (CamelDListNode *)pc);
 		return FALSE;
 	}
@@ -333,7 +333,7 @@ camel_pop3_engine_iterate (CamelPOP3Engine *pe, CamelPOP3Command *pcwait)
 		    && pe->current != NULL)
 			break;
 
-		if (camel_stream_write ((CamelStream *)pe->stream, pw->data, strlen (pw->data), NULL) == -1)
+		if (camel_stream_write ((CamelStream *)pe->stream, pw->data, strlen (pw->data), NULL, NULL) == -1)
 			goto ioerror;
 
 		camel_dlist_remove ((CamelDListNode *)pw);
diff --git a/camel/providers/pop3/camel-pop3-folder.c b/camel/providers/pop3/camel-pop3-folder.c
index b77129e..c01e8eb 100644
--- a/camel/providers/pop3/camel-pop3-folder.c
+++ b/camel/providers/pop3/camel-pop3-folder.c
@@ -38,99 +38,45 @@
 
 #define d(x)
 
-static gboolean pop3_refresh_info (CamelFolder *folder, GError **error);
-static gboolean pop3_sync (CamelFolder *folder, gboolean expunge, GError **error);
-static gint pop3_get_message_count (CamelFolder *folder);
-static GPtrArray *pop3_get_uids (CamelFolder *folder);
-static CamelMimeMessage *pop3_get_message (CamelFolder *folder, const gchar *uid, GError **error);
-static gboolean pop3_set_message_flags (CamelFolder *folder, const gchar *uid, guint32 flags, guint32 set);
-static gchar * pop3_get_filename (CamelFolder *folder, const gchar *uid, GError **error);
-
 G_DEFINE_TYPE (CamelPOP3Folder, camel_pop3_folder, CAMEL_TYPE_FOLDER)
 
 static void
-pop3_folder_dispose (GObject *object)
+cmd_uidl (CamelPOP3Engine *pe,
+          CamelPOP3Stream *stream,
+          gpointer data)
 {
-	CamelPOP3Folder *pop3_folder = CAMEL_POP3_FOLDER (object);
-	CamelPOP3FolderInfo **fi = (CamelPOP3FolderInfo **)pop3_folder->uids->pdata;
-	CamelPOP3Store *pop3_store;
-	CamelStore *parent_store;
-	gint i;
-
-	parent_store = camel_folder_get_parent_store (CAMEL_FOLDER (object));
-	if (parent_store) {
-		pop3_store = CAMEL_POP3_STORE (parent_store);
+	gint ret;
+	guint len;
+	guchar *line;
+	gchar uid[1025];
+	guint id;
+	CamelPOP3FolderInfo *fi;
+	CamelPOP3Folder *folder = data;
 
-		if (pop3_folder->uids) {
-			for (i = 0; i < pop3_folder->uids->len; i++, fi++) {
-				if (fi[0]->cmd) {
-					while (camel_pop3_engine_iterate (pop3_store->engine, fi[0]->cmd) > 0)
-						;
-					camel_pop3_engine_command_free (pop3_store->engine, fi[0]->cmd);
+	do {
+		ret = camel_pop3_stream_line(stream, &line, &len);
+		if (ret>=0) {
+			if (strlen((gchar *) line) > 1024)
+				line[1024] = 0;
+			if (sscanf((gchar *) line, "%u %s", &id, uid) == 2) {
+				fi = g_hash_table_lookup(folder->uids_id, GINT_TO_POINTER(id));
+				if (fi) {
+					camel_operation_progress (NULL, (fi->index+1) * 100 / folder->uids->len);
+					fi->uid = g_strdup(uid);
+					g_hash_table_insert(folder->uids_uid, fi->uid, fi);
+				} else {
+					g_warning("ID %u (uid: %s) not in previous LIST output", id, uid);
 				}
-
-				g_free (fi[0]->uid);
-				g_free (fi[0]);
 			}
-
-			g_ptr_array_free (pop3_folder->uids, TRUE);
-			g_hash_table_destroy (pop3_folder->uids_uid);
 		}
-	}
-
-	/* Chain up to parent's dispose() method. */
-	G_OBJECT_CLASS (camel_pop3_folder_parent_class)->dispose (object);
-}
-
-static void
-camel_pop3_folder_class_init (CamelPOP3FolderClass *class)
-{
-	GObjectClass *object_class;
-	CamelFolderClass *folder_class;
-
-	object_class = G_OBJECT_CLASS (class);
-	object_class->dispose = pop3_folder_dispose;
-
-	folder_class = CAMEL_FOLDER_CLASS (class);
-	folder_class->refresh_info = pop3_refresh_info;
-	folder_class->sync = pop3_sync;
-	folder_class->get_message_count = pop3_get_message_count;
-	folder_class->get_uids = pop3_get_uids;
-	folder_class->free_uids = camel_folder_free_shallow;
-	folder_class->get_filename = pop3_get_filename;
-	folder_class->get_message = pop3_get_message;
-	folder_class->set_message_flags = pop3_set_message_flags;
-}
-
-static void
-camel_pop3_folder_init (CamelPOP3Folder *pop3_folder)
-{
-}
-
-CamelFolder *
-camel_pop3_folder_new (CamelStore *parent, GError **error)
-{
-	CamelFolder *folder;
-
-	d(printf("opening pop3 INBOX folder\n"));
-
-	folder = g_object_new (
-		CAMEL_TYPE_POP3_FOLDER,
-		"full-name", "inbox", "name", "inbox",
-		"parent-store", parent, NULL);
-
-	/* mt-ok, since we dont have the folder-lock for new() */
-	if (!camel_folder_refresh_info (folder, error)) { /* mt-ok */
-		g_object_unref (folder);
-		folder = NULL;
-	}
-
-	return folder;
+	} while (ret>0);
 }
 
 /* create a uid from md5 of 'top' output */
 static void
-cmd_builduid (CamelPOP3Engine *pe, CamelPOP3Stream *stream, gpointer data)
+cmd_builduid (CamelPOP3Engine *pe,
+              CamelPOP3Stream *stream,
+              gpointer data)
 {
 	GChecksum *checksum;
 	CamelPOP3FolderInfo *fi = data;
@@ -206,37 +152,88 @@ cmd_list (CamelPOP3Engine *pe, CamelPOP3Stream *stream, gpointer data)
 }
 
 static void
-cmd_uidl (CamelPOP3Engine *pe, CamelPOP3Stream *stream, gpointer data)
+cmd_tocache (CamelPOP3Engine *pe,
+             CamelPOP3Stream *stream,
+             gpointer data)
 {
-	gint ret;
-	guint len;
-	guchar *line;
-	gchar uid[1025];
-	guint id;
-	CamelPOP3FolderInfo *fi;
-	CamelPOP3Folder *folder = data;
+	CamelPOP3FolderInfo *fi = data;
+	gchar buffer[2048];
+	gint w = 0, n;
 
-	do {
-		ret = camel_pop3_stream_line (stream, &line, &len);
-		if (ret>=0) {
-			if (strlen ((gchar *) line) > 1024)
-				line[1024] = 0;
-			if (sscanf((gchar *) line, "%u %s", &id, uid) == 2) {
-				fi = g_hash_table_lookup (folder->uids_id, GINT_TO_POINTER (id));
-				if (fi) {
-					camel_operation_progress (NULL, (fi->index+1) * 100 / folder->uids->len);
-					fi->uid = g_strdup (uid);
-					g_hash_table_insert (folder->uids_uid, fi->uid, fi);
-				} else {
-					g_warning("ID %u (uid: %s) not in previous LIST output", id, uid);
+	/* What if it fails? */
+
+	/* We write an '*' to the start of the stream to say its not complete yet */
+	/* This should probably be part of the cache code */
+	if ((n = camel_stream_write (fi->stream, "*", 1, NULL, NULL)) == -1)
+		goto done;
+
+	while ((n = camel_stream_read((CamelStream *)stream, buffer, sizeof(buffer), NULL, NULL)) > 0) {
+		n = camel_stream_write(fi->stream, buffer, n, NULL, NULL);
+		if (n == -1)
+			break;
+
+		w += n;
+		if (w > fi->size)
+			w = fi->size;
+		if (fi->size != 0)
+			camel_operation_progress(NULL, (w * 100) / fi->size);
+	}
+
+	/* it all worked, output a '#' to say we're a-ok */
+	if (n != -1) {
+		camel_stream_reset(fi->stream, NULL);
+		n = camel_stream_write(fi->stream, "#", 1, NULL, NULL);
+	}
+done:
+	if (n == -1) {
+		fi->err = errno;
+		g_warning("POP3 retrieval failed: %s", g_strerror(errno));
+	} else {
+		fi->err = 0;
+	}
+
+	g_object_unref (fi->stream);
+	fi->stream = NULL;
+}
+
+static void
+pop3_folder_dispose (GObject *object)
+{
+	CamelPOP3Folder *pop3_folder = CAMEL_POP3_FOLDER (object);
+	CamelPOP3FolderInfo **fi = (CamelPOP3FolderInfo **)pop3_folder->uids->pdata;
+	CamelPOP3Store *pop3_store;
+	CamelStore *parent_store;
+	gint i;
+
+	parent_store = camel_folder_get_parent_store (CAMEL_FOLDER (object));
+	if (parent_store) {
+		pop3_store = CAMEL_POP3_STORE (parent_store);
+
+		if (pop3_folder->uids) {
+			for (i = 0; i < pop3_folder->uids->len; i++, fi++) {
+				if (fi[0]->cmd) {
+					while (camel_pop3_engine_iterate (pop3_store->engine, fi[0]->cmd) > 0)
+						;
+					camel_pop3_engine_command_free (pop3_store->engine, fi[0]->cmd);
 				}
+
+				g_free (fi[0]->uid);
+				g_free (fi[0]);
 			}
+
+			g_ptr_array_free (pop3_folder->uids, TRUE);
+			g_hash_table_destroy (pop3_folder->uids_uid);
 		}
-	} while (ret>0);
+	}
+
+	/* Chain up to parent's dispose() method. */
+	G_OBJECT_CLASS (camel_pop3_folder_parent_class)->dispose (object);
 }
 
 static gboolean
-pop3_refresh_info (CamelFolder *folder, GError **error)
+pop3_folder_refresh_info (CamelFolder *folder,
+                          GCancellable *cancellable,
+                          GError **error)
 {
 	CamelStore *parent_store;
 	CamelPOP3Store *pop3_store;
@@ -248,7 +245,7 @@ pop3_refresh_info (CamelFolder *folder, GError **error)
 	parent_store = camel_folder_get_parent_store (folder);
 	pop3_store = CAMEL_POP3_STORE (parent_store);
 
-	camel_operation_start (NULL, _("Retrieving POP summary"));
+	camel_operation_start (cancellable, _("Retrieving POP summary"));
 
 	pop3_folder->uids = g_ptr_array_new ();
 	pop3_folder->uids_uid = g_hash_table_new (g_str_hash, g_str_equal);
@@ -297,15 +294,16 @@ pop3_refresh_info (CamelFolder *folder, GError **error)
 	/* dont need this anymore */
 	g_hash_table_destroy (pop3_folder->uids_id);
 
-	camel_operation_end (NULL);
+	camel_operation_end (cancellable);
 
 	return success;
 }
 
 static gboolean
-pop3_sync (CamelFolder *folder,
-           gboolean expunge,
-           GError **error)
+pop3_folder_sync (CamelFolder *folder,
+                  gboolean expunge,
+                  GCancellable *cancellable,
+                  GError **error)
 {
 	CamelStore *parent_store;
 	CamelPOP3Folder *pop3_folder;
@@ -321,15 +319,17 @@ pop3_sync (CamelFolder *folder,
 	if (pop3_store->delete_after && !expunge) {
 		d(printf("%s(%d): pop3_store->delete_after = [%d], expunge=[%d]\n",
 			 __FILE__, __LINE__, pop3_store->delete_after, expunge));
-		camel_operation_start(NULL, _("Expunging old messages"));
-		camel_pop3_delete_old (folder, pop3_store->delete_after, error);
+		camel_operation_start (cancellable, _("Expunging old messages"));
+		camel_pop3_delete_old (
+			folder, pop3_store->delete_after,
+			cancellable, error);
 	}
 
 	if (!expunge) {
 		return TRUE;
 	}
 
-	camel_operation_start(NULL, _("Expunging deleted messages"));
+	camel_operation_start (cancellable, _("Expunging deleted messages"));
 
 	for (i = 0; i < pop3_folder->uids->len; i++) {
 		fi = pop3_folder->uids->pdata[i];
@@ -364,189 +364,45 @@ pop3_sync (CamelFolder *folder,
 			camel_pop3_engine_command_free (pop3_store->engine, fi->cmd);
 			fi->cmd = NULL;
 		}
-		camel_operation_progress (NULL, (i+1) * 100 / pop3_folder->uids->len);
+		camel_operation_progress (
+			cancellable, (i+1) * 100 / pop3_folder->uids->len);
 	}
 
-	camel_operation_end (NULL);
+	camel_operation_end (cancellable);
 
 	camel_pop3_store_expunge (pop3_store, error);
 
 	return TRUE;
 }
 
-static gboolean
-pop3_get_message_time_from_cache (CamelFolder *folder, const gchar *uid, time_t *message_time)
+static gint
+pop3_folder_get_message_count (CamelFolder *folder)
 {
-	CamelStore *parent_store;
-	CamelPOP3Store *pop3_store;
-	CamelStream *stream = NULL;
-	gchar buffer[1];
-	gboolean res = FALSE;
-
-	g_return_val_if_fail (folder != NULL, FALSE);
-	g_return_val_if_fail (uid != NULL, FALSE);
-	g_return_val_if_fail (message_time != NULL, FALSE);
-
-	parent_store = camel_folder_get_parent_store (folder);
-	pop3_store = CAMEL_POP3_STORE (parent_store);
-
-	g_return_val_if_fail (pop3_store->cache != NULL, FALSE);
-
-	if ((stream = camel_data_cache_get (pop3_store->cache, "cache", uid, NULL)) != NULL
-	    && camel_stream_read (stream, buffer, 1, NULL) == 1
-	    && buffer[0] == '#') {
-		CamelMimeMessage *message;
-
-		message = camel_mime_message_new ();
-		if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)message, stream, NULL) == -1) {
-			g_warning (_("Cannot get message %s: %s"), uid, g_strerror (errno));
-			g_object_unref (message);
-			message = NULL;
-		}
-
-		if (message) {
-			res = TRUE;
-			*message_time = message->date + message->date_offset;
-
-			g_object_unref (message);
-		}
-	}
+	CamelPOP3Folder *pop3_folder = CAMEL_POP3_FOLDER (folder);
 
-	if (stream) {
-		g_object_unref (stream);
-	}
-	return res;
+	return pop3_folder->uids->len;
 }
 
-gint
-camel_pop3_delete_old (CamelFolder *folder,
-                       gint days_to_delete,
-                       GError **error)
+static GPtrArray *
+pop3_folder_get_uids (CamelFolder *folder)
 {
-	CamelStore *parent_store;
-	CamelPOP3Folder *pop3_folder;
-	CamelPOP3FolderInfo *fi;
+	CamelPOP3Folder *pop3_folder = CAMEL_POP3_FOLDER (folder);
+	GPtrArray *uids = g_ptr_array_new();
+	CamelPOP3FolderInfo **fi = (CamelPOP3FolderInfo **)pop3_folder->uids->pdata;
 	gint i;
-	CamelPOP3Store *pop3_store;
-	CamelMimeMessage *message;
-	time_t temp, message_time = 0;
-
-	parent_store = camel_folder_get_parent_store (folder);
 
-	pop3_folder = CAMEL_POP3_FOLDER (folder);
-	pop3_store = CAMEL_POP3_STORE (parent_store);
-	temp = time (&temp);
-
-	d(printf("%s(%d): pop3_folder->uids->len=[%d]\n", __FILE__, __LINE__, pop3_folder->uids->len));
-	for (i = 0; i < pop3_folder->uids->len; i++) {
-		fi = pop3_folder->uids->pdata[i];
-
-		d(printf("%s(%d): fi->uid=[%s]\n", __FILE__, __LINE__, fi->uid));
-		if (!pop3_get_message_time_from_cache (folder, fi->uid, &message_time)) {
-			d(printf("could not get message time from cache, trying from pop3\n"));
-			message = pop3_get_message (folder, fi->uid, error);
-			if (message) {
-				message_time = message->date + message->date_offset;
-				g_object_unref (message);
-			}
-		}
-
-		if (message_time) {
-			gdouble time_diff = difftime (temp,message_time);
-			gint day_lag = time_diff/(60*60*24);
-
-			d(printf("%s(%d): message_time= [%ld]\n", __FILE__, __LINE__, message_time));
-			d(printf("%s(%d): day_lag=[%d] \t days_to_delete=[%d]\n",
-				__FILE__, __LINE__, day_lag, days_to_delete));
-
-			if (day_lag > days_to_delete) {
-				if (fi->cmd) {
-					while (camel_pop3_engine_iterate (pop3_store->engine, fi->cmd) > 0) {
-						; /* do nothing - iterating until end */
-					}
-
-					camel_pop3_engine_command_free (pop3_store->engine, fi->cmd);
-					fi->cmd = NULL;
-				}
-				d(printf("%s(%d): Deleting old messages\n", __FILE__, __LINE__));
-				fi->cmd = camel_pop3_engine_command_new (pop3_store->engine,
-									0,
-									NULL,
-									NULL,
-									"DELE %u\r\n",
-									fi->id);
-				/* also remove from cache */
-				if (pop3_store->cache && fi->uid) {
-					camel_data_cache_remove(pop3_store->cache, "cache", fi->uid, NULL);
-				}
-			}
-		}
-	}
-
-	for (i = 0; i < pop3_folder->uids->len; i++) {
-		fi = pop3_folder->uids->pdata[i];
-		/* wait for delete commands to finish */
-		if (fi->cmd) {
-			while (camel_pop3_engine_iterate (pop3_store->engine, fi->cmd) > 0)
-				;
-			camel_pop3_engine_command_free (pop3_store->engine, fi->cmd);
-			fi->cmd = NULL;
-		}
-		camel_operation_progress (NULL, (i+1) * 100 / pop3_folder->uids->len);
-	}
-
-	camel_operation_end (NULL);
-
-	camel_pop3_store_expunge (pop3_store, error);
-
-	return 0;
-}
-
-static void
-cmd_tocache (CamelPOP3Engine *pe, CamelPOP3Stream *stream, gpointer data)
-{
-	CamelPOP3FolderInfo *fi = data;
-	gchar buffer[2048];
-	gint w = 0, n;
-
-	/* What if it fails? */
-
-	/* We write an '*' to the start of the stream to say its not complete yet */
-	/* This should probably be part of the cache code */
-	if ((n = camel_stream_write (fi->stream, "*", 1, NULL)) == -1)
-		goto done;
-
-	while ((n = camel_stream_read ((CamelStream *)stream, buffer, sizeof (buffer), NULL)) > 0) {
-		n = camel_stream_write (fi->stream, buffer, n, NULL);
-		if (n == -1)
-			break;
-
-		w += n;
-		if (w > fi->size)
-			w = fi->size;
-		if (fi->size != 0)
-			camel_operation_progress (NULL, (w * 100) / fi->size);
-	}
-
-	/* it all worked, output a '#' to say we're a-ok */
-	if (n != -1) {
-		camel_stream_reset (fi->stream, NULL);
-		n = camel_stream_write(fi->stream, "#", 1, NULL);
-	}
-done:
-	if (n == -1) {
-		fi->err = errno;
-		g_warning("POP3 retrieval failed: %s", g_strerror(errno));
-	} else {
-		fi->err = 0;
+	for (i=0;i<pop3_folder->uids->len;i++,fi++) {
+		if (fi[0]->uid)
+			g_ptr_array_add(uids, fi[0]->uid);
 	}
 
-	g_object_unref (fi->stream);
-	fi->stream = NULL;
+	return uids;
 }
 
 static gchar *
-pop3_get_filename (CamelFolder *folder, const gchar *uid, GError **error)
+pop3_folder_get_filename (CamelFolder *folder,
+                          const gchar *uid,
+                          GError **error)
 {
 	CamelStore *parent_store;
 	CamelPOP3Folder *pop3_folder;
@@ -558,7 +414,7 @@ pop3_get_filename (CamelFolder *folder, const gchar *uid, GError **error)
 	pop3_folder = CAMEL_POP3_FOLDER (folder);
 	pop3_store = CAMEL_POP3_STORE (parent_store);
 
-	fi = g_hash_table_lookup (pop3_folder->uids_uid, uid);
+	fi = g_hash_table_lookup(pop3_folder->uids_uid, uid);
 	if (fi == NULL) {
 		g_set_error (
 			error, CAMEL_FOLDER_ERROR,
@@ -567,11 +423,15 @@ pop3_get_filename (CamelFolder *folder, const gchar *uid, GError **error)
 		return NULL;
 	}
 
-	return camel_data_cache_get_filename (pop3_store->cache, "cache", fi->uid, NULL);
+	return camel_data_cache_get_filename (
+		pop3_store->cache, "cache", fi->uid, NULL);
 }
 
 static CamelMimeMessage *
-pop3_get_message (CamelFolder *folder, const gchar *uid, GError **error)
+pop3_folder_get_message (CamelFolder *folder,
+                         const gchar *uid,
+                         GCancellable *cancellable,
+                         GError **error)
 {
 	CamelStore *parent_store;
 	CamelMimeMessage *message = NULL;
@@ -600,7 +460,8 @@ pop3_get_message (CamelFolder *folder, const gchar *uid, GError **error)
 	/* Sigh, most of the crap in this function is so that the cancel button
 	   returns the proper exception code.  Sigh. */
 
-	camel_operation_start_transient(NULL, _("Retrieving POP message %d"), fi->id);
+	camel_operation_start_transient (
+		cancellable, _("Retrieving POP message %d"), fi->id);
 
 	/* If we have an oustanding retrieve message running, wait for that to complete
 	   & then retrieve from cache, otherwise, start a new one, and similar */
@@ -636,7 +497,7 @@ pop3_get_message (CamelFolder *folder, const gchar *uid, GError **error)
 	/* check to see if we have safely written flag set */
 	if (pop3_store->cache == NULL
 	    || (stream = camel_data_cache_get(pop3_store->cache, "cache", fi->uid, NULL)) == NULL
-	    || camel_stream_read (stream, buffer, 1, NULL) != 1
+	    || camel_stream_read (stream, buffer, 1, cancellable, NULL) != 1
 	    || buffer[0] != '#') {
 
 		/* Initiate retrieval, if disk backing fails, use a memory backing */
@@ -697,7 +558,8 @@ pop3_get_message (CamelFolder *folder, const gchar *uid, GError **error)
 			goto done;
 		}
 
-		if (camel_stream_read (stream, buffer, 1, error) == -1)
+		if (camel_stream_read (
+			stream, buffer, 1, cancellable, error) == -1)
 			goto done;
 
 		if (buffer[0] != '#') {
@@ -710,7 +572,8 @@ pop3_get_message (CamelFolder *folder, const gchar *uid, GError **error)
 	}
 
 	message = camel_mime_message_new ();
-	if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)message, stream, error) == -1) {
+	if (camel_data_wrapper_construct_from_stream (
+		CAMEL_DATA_WRAPPER (message), stream, cancellable, error) == -1) {
 		g_prefix_error (error, _("Cannot get message %s: "), uid);
 		g_object_unref (message);
 		message = NULL;
@@ -718,13 +581,16 @@ pop3_get_message (CamelFolder *folder, const gchar *uid, GError **error)
 done:
 	g_object_unref (stream);
 fail:
-	camel_operation_end (NULL);
+	camel_operation_end (cancellable);
 
 	return message;
 }
 
 static gboolean
-pop3_set_message_flags (CamelFolder *folder, const gchar *uid, guint32 flags, guint32 set)
+pop3_folder_set_message_flags (CamelFolder *folder,
+                               const gchar *uid,
+                               guint32 flags,
+                               guint32 set)
 {
 	CamelPOP3Folder *pop3_folder = CAMEL_POP3_FOLDER (folder);
 	CamelPOP3FolderInfo *fi;
@@ -743,26 +609,182 @@ pop3_set_message_flags (CamelFolder *folder, const gchar *uid, guint32 flags, gu
 	return res;
 }
 
-static gint
-pop3_get_message_count (CamelFolder *folder)
+static void
+camel_pop3_folder_class_init (CamelPOP3FolderClass *class)
 {
-	CamelPOP3Folder *pop3_folder = CAMEL_POP3_FOLDER (folder);
+	GObjectClass *object_class;
+	CamelFolderClass *folder_class;
 
-	return pop3_folder->uids->len;
+	object_class = G_OBJECT_CLASS (class);
+	object_class->dispose = pop3_folder_dispose;
+
+	folder_class = CAMEL_FOLDER_CLASS (class);
+	folder_class->refresh_info = pop3_folder_refresh_info;
+	folder_class->sync = pop3_folder_sync;
+	folder_class->get_message_count = pop3_folder_get_message_count;
+	folder_class->get_uids = pop3_folder_get_uids;
+	folder_class->free_uids = camel_folder_free_shallow;
+	folder_class->get_filename = pop3_folder_get_filename;
+	folder_class->get_message = pop3_folder_get_message;
+	folder_class->set_message_flags = pop3_folder_set_message_flags;
 }
 
-static GPtrArray *
-pop3_get_uids (CamelFolder *folder)
+static void
+camel_pop3_folder_init (CamelPOP3Folder *pop3_folder)
 {
-	CamelPOP3Folder *pop3_folder = CAMEL_POP3_FOLDER (folder);
-	GPtrArray *uids = g_ptr_array_new ();
-	CamelPOP3FolderInfo **fi = (CamelPOP3FolderInfo **)pop3_folder->uids->pdata;
+}
+
+CamelFolder *
+camel_pop3_folder_new (CamelStore *parent,
+                       GCancellable *cancellable,
+                       GError **error)
+{
+	CamelFolder *folder;
+
+	d(printf("opening pop3 INBOX folder\n"));
+
+	folder = g_object_new (
+		CAMEL_TYPE_POP3_FOLDER,
+		"full-name", "inbox", "name", "inbox",
+		"parent-store", parent, NULL);
+
+	/* mt-ok, since we dont have the folder-lock for new() */
+	if (!camel_folder_refresh_info (folder, cancellable, error)) {
+		g_object_unref (folder);
+		folder = NULL;
+	}
+
+	return folder;
+}
+
+static gboolean
+pop3_get_message_time_from_cache (CamelFolder *folder, const gchar *uid, time_t *message_time)
+{
+	CamelStore *parent_store;
+	CamelPOP3Store *pop3_store;
+	CamelStream *stream = NULL;
+	gchar buffer[1];
+	gboolean res = FALSE;
+
+	g_return_val_if_fail (folder != NULL, FALSE);
+	g_return_val_if_fail (uid != NULL, FALSE);
+	g_return_val_if_fail (message_time != NULL, FALSE);
+
+	parent_store = camel_folder_get_parent_store (folder);
+	pop3_store = CAMEL_POP3_STORE (parent_store);
+
+	g_return_val_if_fail (pop3_store->cache != NULL, FALSE);
+
+	if ((stream = camel_data_cache_get (pop3_store->cache, "cache", uid, NULL)) != NULL
+	    && camel_stream_read (stream, buffer, 1, NULL, NULL) == 1
+	    && buffer[0] == '#') {
+		CamelMimeMessage *message;
+
+		message = camel_mime_message_new ();
+		if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)message, stream, NULL, NULL) == -1) {
+			g_warning (_("Cannot get message %s: %s"), uid, g_strerror (errno));
+			g_object_unref (message);
+			message = NULL;
+		}
+
+		if (message) {
+			res = TRUE;
+			*message_time = message->date + message->date_offset;
+
+			g_object_unref (message);
+		}
+	}
+
+	if (stream) {
+		g_object_unref (stream);
+	}
+	return res;
+}
+
+gint
+camel_pop3_delete_old (CamelFolder *folder,
+                       gint days_to_delete,
+                       GCancellable *cancellable,
+                       GError **error)
+{
+	CamelStore *parent_store;
+	CamelPOP3Folder *pop3_folder;
+	CamelPOP3FolderInfo *fi;
 	gint i;
+	CamelPOP3Store *pop3_store;
+	CamelMimeMessage *message;
+	time_t temp, message_time = 0;
 
-	for (i=0;i<pop3_folder->uids->len;i++,fi++) {
-		if (fi[0]->uid)
-			g_ptr_array_add (uids, fi[0]->uid);
+	parent_store = camel_folder_get_parent_store (folder);
+
+	pop3_folder = CAMEL_POP3_FOLDER (folder);
+	pop3_store = CAMEL_POP3_STORE (parent_store);
+	temp = time(&temp);
+
+	d(printf("%s(%d): pop3_folder->uids->len=[%d]\n", __FILE__, __LINE__, pop3_folder->uids->len));
+	for (i = 0; i < pop3_folder->uids->len; i++) {
+		fi = pop3_folder->uids->pdata[i];
+
+		d(printf("%s(%d): fi->uid=[%s]\n", __FILE__, __LINE__, fi->uid));
+		if (!pop3_get_message_time_from_cache (folder, fi->uid, &message_time)) {
+			d(printf("could not get message time from cache, trying from pop3\n"));
+			message = pop3_folder_get_message (
+				folder, fi->uid, cancellable, error);
+			if (message) {
+				message_time = message->date + message->date_offset;
+				g_object_unref (message);
+			}
+		}
+
+		if (message_time) {
+			gdouble time_diff = difftime(temp,message_time);
+			gint day_lag = time_diff/(60*60*24);
+
+			d(printf("%s(%d): message_time= [%ld]\n", __FILE__, __LINE__, message_time));
+			d(printf("%s(%d): day_lag=[%d] \t days_to_delete=[%d]\n",
+				__FILE__, __LINE__, day_lag, days_to_delete));
+
+			if (day_lag > days_to_delete) {
+				if (fi->cmd) {
+					while (camel_pop3_engine_iterate(pop3_store->engine, fi->cmd) > 0) {
+						; /* do nothing - iterating until end */
+					}
+
+					camel_pop3_engine_command_free(pop3_store->engine, fi->cmd);
+					fi->cmd = NULL;
+				}
+				d(printf("%s(%d): Deleting old messages\n", __FILE__, __LINE__));
+				fi->cmd = camel_pop3_engine_command_new(pop3_store->engine,
+									0,
+									NULL,
+									NULL,
+									"DELE %u\r\n",
+									fi->id);
+				/* also remove from cache */
+				if (pop3_store->cache && fi->uid) {
+					camel_data_cache_remove(pop3_store->cache, "cache", fi->uid, NULL);
+				}
+			}
+		}
 	}
 
-	return uids;
+	for (i = 0; i < pop3_folder->uids->len; i++) {
+		fi = pop3_folder->uids->pdata[i];
+		/* wait for delete commands to finish */
+		if (fi->cmd) {
+			while (camel_pop3_engine_iterate(pop3_store->engine, fi->cmd) > 0)
+				;
+			camel_pop3_engine_command_free(pop3_store->engine, fi->cmd);
+			fi->cmd = NULL;
+		}
+		camel_operation_progress (
+			cancellable, (i+1) * 100 / pop3_folder->uids->len);
+	}
+
+	camel_operation_end (cancellable);
+
+	camel_pop3_store_expunge (pop3_store, error);
+
+	return 0;
 }
+
diff --git a/camel/providers/pop3/camel-pop3-folder.h b/camel/providers/pop3/camel-pop3-folder.h
index d5edd0d..6a5592a 100644
--- a/camel/providers/pop3/camel-pop3-folder.h
+++ b/camel/providers/pop3/camel-pop3-folder.h
@@ -76,12 +76,14 @@ struct _CamelPOP3FolderClass {
 	CamelFolderClass parent_class;
 };
 
-/* public methods */
-CamelFolder *camel_pop3_folder_new (CamelStore *parent, GError **error);
-
-GType camel_pop3_folder_get_type (void);
-
-gint camel_pop3_delete_old (CamelFolder *folder, gint days_to_delete, GError **error);
+GType		camel_pop3_folder_get_type	(void);
+CamelFolder *	camel_pop3_folder_new		(CamelStore *parent,
+						 GCancellable *cancellable,
+						 GError **error);
+gint		camel_pop3_delete_old		(CamelFolder *folder,
+						 gint days_to_delete,
+						 GCancellable *cancellable,
+						 GError **error);
 
 G_END_DECLS
 
diff --git a/camel/providers/pop3/camel-pop3-store.c b/camel/providers/pop3/camel-pop3-store.c
index 1c92143..39cc238 100644
--- a/camel/providers/pop3/camel-pop3-store.c
+++ b/camel/providers/pop3/camel-pop3-store.c
@@ -103,8 +103,11 @@ get_valid_utf8_error (const gchar *text)
 
 static gboolean
 connect_to_server (CamelService *service,
-		   const gchar *host, const gchar *serv, gint fallback_port,
+                   const gchar *host,
+                   const gchar *serv,
+                   gint fallback_port,
                    gint ssl_mode,
+                   GCancellable *cancellable,
                    GError **error)
 {
 	CamelPOP3Store *store = CAMEL_POP3_STORE (service);
@@ -141,17 +144,21 @@ connect_to_server (CamelService *service,
 	camel_session_get_socks_proxy (session, &socks_host, &socks_port);
 
 	if (socks_host) {
-		camel_tcp_stream_set_socks_proxy ((CamelTcpStream *) tcp_stream, socks_host, socks_port);
+		camel_tcp_stream_set_socks_proxy (
+			CAMEL_TCP_STREAM (tcp_stream),
+			socks_host, socks_port);
 		g_free (socks_host);
 	}
 
-	if (camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, host, serv, fallback_port, error) == -1) {
+	if (camel_tcp_stream_connect (
+		CAMEL_TCP_STREAM (tcp_stream), host, serv,
+		fallback_port, cancellable, error) == -1) {
 		g_object_unref (tcp_stream);
 		return FALSE;
 	}
 
 	/* parent class connect initialization */
-	if (CAMEL_SERVICE_CLASS (camel_pop3_store_parent_class)->connect (service, error) == FALSE) {
+	if (CAMEL_SERVICE_CLASS (camel_pop3_store_parent_class)->connect (service, cancellable, error) == FALSE) {
 		g_object_unref (tcp_stream);
 		return FALSE;
 	}
@@ -252,6 +259,7 @@ connect_to_server (CamelService *service,
 
 static gboolean
 connect_to_server_wrapper (CamelService *service,
+                           GCancellable *cancellable,
                            GError **error)
 {
 	const gchar *ssl_mode;
@@ -278,12 +286,15 @@ connect_to_server_wrapper (CamelService *service,
 		fallback_port = 0;
 	}
 
-	return connect_to_server (service, service->url->host, serv, fallback_port, mode, error);
+	return connect_to_server (
+		service, service->url->host, serv,
+		fallback_port, mode, cancellable, error);
 }
 
 static gint
 try_sasl (CamelPOP3Store *store,
           const gchar *mech,
+          GCancellable *cancellable,
           GError **error)
 {
 	CamelPOP3Stream *stream = store->engine->stream;
@@ -330,8 +341,8 @@ try_sasl (CamelPOP3Store *store,
 		/* If we dont get continuation, or the sasl object's run out of work, or we dont get a challenge,
 		   its a protocol error, so fail, and try reset the server */
 		if (strncmp((gchar *) line, "+ ", 2) != 0
-		    || camel_sasl_get_authenticated (sasl)
-		    || (resp = (guchar *) camel_sasl_challenge_base64 (sasl, (const gchar *) line+2, error)) == NULL) {
+		    || camel_sasl_get_authenticated(sasl)
+		    || (resp = (guchar *) camel_sasl_challenge_base64(sasl, (const gchar *) line+2, cancellable, NULL)) == NULL) {
 			camel_stream_printf((CamelStream *)stream, "*\r\n");
 			camel_pop3_stream_line (stream, &line, &len);
 			g_set_error (
@@ -366,6 +377,7 @@ static gint
 pop3_try_authenticate (CamelService *service,
                        gboolean reprompt,
                        const gchar *errmsg,
+                       GCancellable *cancellable,
                        GError **error)
 {
 	CamelPOP3Store *store = (CamelPOP3Store *)service;
@@ -441,8 +453,10 @@ pop3_try_authenticate (CamelService *service,
 		l = store->engine->auth;
 		while (l) {
 			auth = l->data;
-			if (strcmp (auth->authproto, service->url->authmech) == 0)
-				return try_sasl (store, service->url->authmech, error);
+			if (strcmp(auth->authproto, service->url->authmech) == 0)
+				return try_sasl (
+					store, service->url->authmech,
+					cancellable, error);
 			l = l->next;
 		}
 
@@ -452,6 +466,7 @@ pop3_try_authenticate (CamelService *service,
 			_("Unable to connect to POP server %s: "
 			  "No support for requested authentication mechanism."),
 			CAMEL_SERVICE (store)->url->host);
+
 		return 0;
 	}
 
@@ -530,6 +545,7 @@ pop3_store_finalize (GObject *object)
 
 static gboolean
 pop3_store_connect (CamelService *service,
+                    GCancellable *cancellable,
                     GError **error)
 {
 	CamelPOP3Store *store = (CamelPOP3Store *)service;
@@ -556,12 +572,13 @@ pop3_store_connect (CamelService *service,
 		}
 	}
 
-	if (!connect_to_server_wrapper (service, error))
+	if (!connect_to_server_wrapper (service, cancellable, error))
 		return FALSE;
 
 	while (1) {
 		status = pop3_try_authenticate (
-			service, reprompt, errbuf, &local_error);
+			service, reprompt, errbuf,
+			cancellable, &local_error);
 		g_free (errbuf);
 		errbuf = NULL;
 
@@ -600,6 +617,7 @@ pop3_store_connect (CamelService *service,
 static gboolean
 pop3_store_disconnect (CamelService *service,
                        gboolean clean,
+                       GCancellable *cancellable,
                        GError **error)
 {
 	CamelServiceClass *service_class;
@@ -616,7 +634,7 @@ pop3_store_disconnect (CamelService *service,
 
 	/* Chain up to parent's disconnect() method. */
 	service_class = CAMEL_SERVICE_CLASS (camel_pop3_store_parent_class);
-	if (!service_class->disconnect (service, clean, error))
+	if (!service_class->disconnect (service, clean, cancellable, error))
 		return FALSE;
 
 	g_object_unref (store->engine);
@@ -627,6 +645,7 @@ pop3_store_disconnect (CamelService *service,
 
 static GList *
 pop3_store_query_auth_types (CamelService *service,
+                             GCancellable *cancellable,
                              GError **error)
 {
 	CamelServiceClass *service_class;
@@ -636,16 +655,17 @@ pop3_store_query_auth_types (CamelService *service,
 
 	/* Chain up to parent's query_auth_types() method. */
 	service_class = CAMEL_SERVICE_CLASS (camel_pop3_store_parent_class);
-	types = service_class->query_auth_types (service, &local_error);
+	types = service_class->query_auth_types (
+		service, cancellable, &local_error);
 
 	if (local_error != NULL) {
 		g_propagate_error (error, local_error);
 		return NULL;
 	}
 
-	if (connect_to_server_wrapper (service, NULL)) {
+	if (connect_to_server_wrapper (service, cancellable, NULL)) {
 		types = g_list_concat (types, g_list_copy (store->engine->auth));
-		pop3_store_disconnect (service, TRUE, NULL);
+		pop3_store_disconnect (service, TRUE, cancellable, NULL);
 	} else {
 		g_set_error (
 			error, CAMEL_SERVICE_ERROR,
@@ -676,6 +696,7 @@ static CamelFolder *
 pop3_store_get_folder (CamelStore *store,
                        const gchar *folder_name,
                        guint32 flags,
+                       GCancellable *cancellable,
                        GError **error)
 {
 	if (g_ascii_strcasecmp (folder_name, "inbox") != 0) {
@@ -686,11 +707,12 @@ pop3_store_get_folder (CamelStore *store,
 		return NULL;
 	}
 
-	return camel_pop3_folder_new (store, error);
+	return camel_pop3_folder_new (store, cancellable, error);
 }
 
 static CamelFolder *
 pop3_store_get_trash (CamelStore *store,
+                      GCancellable *cancellable,
                       GError **error)
 {
 	/* no-op */
@@ -701,6 +723,7 @@ static CamelFolderInfo *
 pop3_store_get_folder_info (CamelStore *store,
                             const gchar *top,
                             guint32 flags,
+                            GCancellable *cancellable,
                             GError **error)
 {
 	g_set_error (
diff --git a/camel/providers/pop3/camel-pop3-stream.c b/camel/providers/pop3/camel-pop3-stream.c
index 39ed3c5..76f8d91 100644
--- a/camel/providers/pop3/camel-pop3-stream.c
+++ b/camel/providers/pop3/camel-pop3-stream.c
@@ -69,6 +69,7 @@ pop3_stream_finalize (GObject *object)
 
 static gint
 stream_fill (CamelPOP3Stream *is,
+             GCancellable *cancellable,
              GError **error)
 {
 	gint left = 0;
@@ -80,7 +81,8 @@ stream_fill (CamelPOP3Stream *is,
 		is->ptr = is->buf;
 		left = camel_stream_read (
 			is->source, (gchar *) is->end,
-			CAMEL_POP3_STREAM_SIZE - (is->end - is->buf), error);
+			CAMEL_POP3_STREAM_SIZE - (is->end - is->buf),
+			cancellable, error);
 		if (left > 0) {
 			is->end += left;
 			is->end[0] = '\n';
@@ -96,6 +98,7 @@ static gssize
 stream_read (CamelStream *stream,
              gchar *buffer,
              gsize n,
+             GCancellable *cancellable,
              GError **error)
 {
 	CamelPOP3Stream *is = (CamelPOP3Stream *)stream;
@@ -119,7 +122,7 @@ stream_read (CamelStream *stream,
 	case 0:		/* start of line, always read at least 3 chars */
 		while (e - p < 3) {
 			is->ptr = p;
-			if (stream_fill (is, error) == -1)
+			if (stream_fill (is, cancellable, error) == -1)
 				return -1;
 			p = is->ptr;
 			e = is->end;
@@ -143,7 +146,7 @@ stream_read (CamelStream *stream,
 				/* end of input sentinal check */
 				if (p > e) {
 					is->ptr = e;
-					if (stream_fill (is, error) == -1)
+					if (stream_fill (is, cancellable, error) == -1)
 						return -1;
 					p = is->ptr;
 					e = is->end;
@@ -171,6 +174,7 @@ static gssize
 stream_write (CamelStream *stream,
               const gchar *buffer,
               gsize n,
+              GCancellable *cancellable,
               GError **error)
 {
 	CamelPOP3Stream *is = (CamelPOP3Stream *)stream;
@@ -180,11 +184,12 @@ stream_write (CamelStream *stream,
 	else
 		dd (printf ("POP3_STREAM_WRITE (%d):\nPASS xxxxxxxx\n", (gint)n));
 
-	return camel_stream_write (is->source, buffer, n, error);
+	return camel_stream_write (is->source, buffer, n, cancellable, error);
 }
 
 static gint
 stream_close (CamelStream *stream,
+              GCancellable *cancellable,
               GError **error)
 {
 	/* nop? */
@@ -193,6 +198,7 @@ stream_close (CamelStream *stream,
 
 static gint
 stream_flush (CamelStream *stream,
+              GCancellable *cancellable,
               GError **error)
 {
 	/* nop? */
@@ -292,7 +298,7 @@ camel_pop3_stream_line (CamelPOP3Stream *is, guchar **data, guint *len)
 		/* need at least 3 chars in buffer */
 		while (e-p < 3) {
 			is->ptr = p;
-			if (stream_fill (is, NULL) == -1)
+			if (stream_fill (is, NULL, NULL) == -1)
 				return -1;
 			p = is->ptr;
 			e = is->end;
@@ -322,7 +328,7 @@ camel_pop3_stream_line (CamelPOP3Stream *is, guchar **data, guint *len)
 				/* sentinal? */
 				if (p> e) {
 					is->ptr = e;
-					if (stream_fill (is, NULL) == -1)
+					if (stream_fill (is, NULL, NULL) == -1)
 						return -1;
 					p = is->ptr;
 					e = is->end;
@@ -363,7 +369,7 @@ gint camel_pop3_stream_gets (CamelPOP3Stream *is, guchar **start, guint *len)
 
 	max = is->end - is->ptr;
 	if (max == 0) {
-		max = stream_fill (is, NULL);
+		max = stream_fill (is, NULL, NULL);
 		if (max <= 0)
 			return max;
 	}
@@ -408,7 +414,7 @@ gint camel_pop3_stream_getd (CamelPOP3Stream *is, guchar **start, guint *len)
 
 	while (e - p < 3) {
 		is->ptr = p;
-		if (stream_fill (is, NULL) == -1)
+		if (stream_fill (is, NULL, NULL) == -1)
 			return -1;
 		p = is->ptr;
 		e = is->end;
diff --git a/camel/providers/sendmail/camel-sendmail-transport.c b/camel/providers/sendmail/camel-sendmail-transport.c
index d857dad..5226bac 100644
--- a/camel/providers/sendmail/camel-sendmail-transport.c
+++ b/camel/providers/sendmail/camel-sendmail-transport.c
@@ -37,31 +37,18 @@
 
 #include "camel-sendmail-transport.h"
 
-static gchar *get_name (CamelService *service, gboolean brief);
+G_DEFINE_TYPE (
+	CamelSendmailTransport,
+	camel_sendmail_transport, CAMEL_TYPE_TRANSPORT)
 
-static gboolean sendmail_send_to (CamelTransport *transport,
-				  CamelMimeMessage *message,
-				  CamelAddress *from, CamelAddress *recipients,
-				  GError **error);
-
-G_DEFINE_TYPE (CamelSendmailTransport, camel_sendmail_transport, CAMEL_TYPE_TRANSPORT)
-
-static void
-camel_sendmail_transport_class_init (CamelSendmailTransportClass *class)
-{
-	CamelServiceClass *service_class;
-	CamelTransportClass *transport_class;
-
-	service_class = CAMEL_SERVICE_CLASS (class);
-	service_class->get_name = get_name;
-
-	transport_class = CAMEL_TRANSPORT_CLASS (class);
-	transport_class->send_to = sendmail_send_to;
-}
-
-static void
-camel_sendmail_transport_init (CamelSendmailTransport *sendmail_transport)
+static gchar *
+sendmail_get_name (CamelService *service,
+                   gboolean brief)
 {
+	if (brief)
+		return g_strdup (_("sendmail"));
+	else
+		return g_strdup (_("Mail delivery via the sendmail program"));
 }
 
 static gboolean
@@ -69,6 +56,7 @@ sendmail_send_to (CamelTransport *transport,
                   CamelMimeMessage *message,
                   CamelAddress *from,
                   CamelAddress *recipients,
+                  GCancellable *cancellable,
                   GError **error)
 {
 	struct _camel_header_raw *header, *savedbcc, *n, *tail;
@@ -188,8 +176,8 @@ sendmail_send_to (CamelTransport *transport,
 
 	out = (CamelStream *) filter;
 	if (camel_data_wrapper_write_to_stream (
-		CAMEL_DATA_WRAPPER (message), out, error) == -1
-	    || camel_stream_close (out, error) == -1) {
+		CAMEL_DATA_WRAPPER (message), out, cancellable, error) == -1
+	    || camel_stream_close (out, cancellable, error) == -1) {
 		g_object_unref (CAMEL_OBJECT (out));
 		g_prefix_error (error, _("Could not send message: "));
 
@@ -241,11 +229,21 @@ sendmail_send_to (CamelTransport *transport,
 	return TRUE;
 }
 
-static gchar *
-get_name (CamelService *service, gboolean brief)
+static void
+camel_sendmail_transport_class_init (CamelSendmailTransportClass *class)
+{
+	CamelServiceClass *service_class;
+	CamelTransportClass *transport_class;
+
+	service_class = CAMEL_SERVICE_CLASS (class);
+	service_class->get_name = sendmail_get_name;
+
+	transport_class = CAMEL_TRANSPORT_CLASS (class);
+	transport_class->send_to = sendmail_send_to;
+}
+
+static void
+camel_sendmail_transport_init (CamelSendmailTransport *sendmail_transport)
 {
-	if (brief)
-		return g_strdup (_("sendmail"));
-	else
-		return g_strdup (_("Mail delivery via the sendmail program"));
 }
+
diff --git a/camel/providers/smtp/camel-smtp-transport.c b/camel/providers/smtp/camel-smtp-transport.c
index 428b3c8..09c4748 100644
--- a/camel/providers/smtp/camel-smtp-transport.c
+++ b/camel/providers/smtp/camel-smtp-transport.c
@@ -54,121 +54,42 @@ extern gint camel_verbose_debug;
 #define SMTP_PORT  25
 #define SMTPS_PORT 465
 
-/* camel smtp transport class prototypes */
-static gboolean smtp_send_to (CamelTransport *transport, CamelMimeMessage *message,
-			      CamelAddress *from, CamelAddress *recipients, GError **error);
-
 /* support prototypes */
-static gboolean smtp_connect (CamelService *service, GError **error);
-static gboolean smtp_disconnect (CamelService *service, gboolean clean, GError **error);
-static GHashTable *esmtp_get_authtypes (const guchar *buffer);
-static GList *query_auth_types (CamelService *service, GError **error);
-static gchar *get_name (CamelService *service, gboolean brief);
-
-static gboolean smtp_helo (CamelSmtpTransport *transport, GError **error);
-static gboolean smtp_auth (CamelSmtpTransport *transport, const gchar *mech, GError **error);
-static gboolean smtp_mail (CamelSmtpTransport *transport, const gchar *sender,
-			   gboolean has_8bit_parts, GError **error);
-static gboolean smtp_rcpt (CamelSmtpTransport *transport, const gchar *recipient, GError **error);
-static gboolean smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, GError **error);
-static gboolean smtp_rset (CamelSmtpTransport *transport, GError **error);
-static gboolean smtp_quit (CamelSmtpTransport *transport, GError **error);
-
-static void smtp_set_error (CamelSmtpTransport *transport, const gchar *respbuf, GError **error);
-
-G_DEFINE_TYPE (CamelSmtpTransport, camel_smtp_transport, CAMEL_TYPE_TRANSPORT)
-
-static void
-camel_smtp_transport_class_init (CamelSmtpTransportClass *class)
-{
-	CamelTransportClass *transport_class;
-	CamelServiceClass *service_class;
-
-	service_class = CAMEL_SERVICE_CLASS (class);
-	service_class->connect = smtp_connect;
-	service_class->disconnect = smtp_disconnect;
-	service_class->query_auth_types = query_auth_types;
-	service_class->get_name = get_name;
-
-	transport_class = CAMEL_TRANSPORT_CLASS (class);
-	transport_class->send_to = smtp_send_to;
-}
-
-static void
-camel_smtp_transport_init (CamelSmtpTransport *smtp)
-{
-	smtp->flags = 0;
-	smtp->connected = FALSE;
-}
-
-static const gchar *
-smtp_error_string (gint error)
-{
-	/* SMTP error codes grabbed from rfc821 */
-	switch (error) {
-	case 0:
-		/* looks like a read problem, check errno */
-		if (errno)
-			return g_strerror (errno);
-		else
-			return _("Unknown");
-	case 500:
-		return _("Syntax error, command unrecognized");
-	case 501:
-		return _("Syntax error in parameters or arguments");
-	case 502:
-		return _("Command not implemented");
-	case 504:
-		return _("Command parameter not implemented");
-	case 211:
-		return _("System status, or system help reply");
-	case 214:
-		return _("Help message");
-	case 220:
-		return _("Service ready");
-	case 221:
-		return _("Service closing transmission channel");
-	case 421:
-		return _("Service not available, closing transmission channel");
-	case 250:
-		return _("Requested mail action okay, completed");
-	case 251:
-		return _("User not local; will forward to <forward-path>");
-	case 450:
-		return _("Requested mail action not taken: mailbox unavailable");
-	case 550:
-		return _("Requested action not taken: mailbox unavailable");
-	case 451:
-		return _("Requested action aborted: error in processing");
-	case 551:
-		return _("User not local; please try <forward-path>");
-	case 452:
-		return _("Requested action not taken: insufficient system storage");
-	case 552:
-		return _("Requested mail action aborted: exceeded storage allocation");
-	case 553:
-		return _("Requested action not taken: mailbox name not allowed");
-	case 354:
-		return _("Start mail input; end with <CRLF>.<CRLF>");
-	case 554:
-		return _("Transaction failed");
-
-	/* AUTH error codes: */
-	case 432:
-		return _("A password transition is needed");
-	case 534:
-		return _("Authentication mechanism is too weak");
-	case 538:
-		return _("Encryption required for requested authentication mechanism");
-	case 454:
-		return _("Temporary authentication failure");
-	case 530:
-		return _("Authentication required");
-
-	default:
-		return _("Unknown");
-	}
-}
+static gboolean		smtp_disconnect		(CamelService *service,
+						 gboolean clean,
+						 GCancellable *cancellable,
+						 GError **error);
+static GHashTable *	esmtp_get_authtypes	(const guchar *buffer);
+static gboolean		smtp_helo		(CamelSmtpTransport *transport,
+						 GCancellable *cancellable,
+						 GError **error);
+static gboolean		smtp_auth		(CamelSmtpTransport *transport,
+						 const gchar *mech,
+						 GCancellable *cancellable,
+						 GError **error);
+static gboolean		smtp_mail		(CamelSmtpTransport *transport,
+						 const gchar *sender,
+						 gboolean has_8bit_parts,
+						 GCancellable *cancellable,
+						 GError **error);
+static gboolean		smtp_rcpt		(CamelSmtpTransport *transport,
+						 const gchar *recipient,
+						 GCancellable *cancellable,
+						 GError **error);
+static gboolean		smtp_data		(CamelSmtpTransport *transport,
+						 CamelMimeMessage *message,
+						 GCancellable *cancellable,
+						 GError **error);
+static gboolean		smtp_rset		(CamelSmtpTransport *transport,
+						 GCancellable *cancellable,
+						 GError **error);
+static gboolean		smtp_quit		(CamelSmtpTransport *transport,
+						 GCancellable *cancellable,
+						 GError **error);
+static void		smtp_set_error		(CamelSmtpTransport *transport,
+						 const gchar *respbuf,
+						 GCancellable *cancellable,
+						 GError **error);
 
 enum {
 	MODE_CLEAR,
@@ -181,10 +102,28 @@ enum {
 #define STARTTLS_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_TLS)
 #endif
 
+static struct {
+	const gchar *value;
+	const gchar *serv;
+	gint fallback_port;
+	gint mode;
+} ssl_options[] = {
+	{ "",              "smtps", SMTPS_PORT, MODE_SSL  },  /* really old (1.x) */
+	{ "always",        "smtps", SMTPS_PORT, MODE_SSL  },
+	{ "when-possible", "smtp",  SMTP_PORT, MODE_TLS   },
+	{ "never",         "smtp",  SMTP_PORT, MODE_CLEAR },
+	{ NULL,            "smtp",  SMTP_PORT, MODE_CLEAR }
+};
+
+G_DEFINE_TYPE (CamelSmtpTransport, camel_smtp_transport, CAMEL_TYPE_TRANSPORT)
+
 static gboolean
 connect_to_server (CamelService *service,
-		   const gchar *host, const gchar *serv, gint fallback_port,
+                   const gchar *host,
+                   const gchar *serv,
+                   gint fallback_port,
                    gint ssl_mode,
+                   GCancellable *cancellable,
                    GError **error)
 {
 	CamelSmtpTransport *transport = CAMEL_SMTP_TRANSPORT (service);
@@ -194,7 +133,8 @@ connect_to_server (CamelService *service,
 	CamelStream *tcp_stream;
 	gchar *respbuf = NULL;
 
-	if (!CAMEL_SERVICE_CLASS (camel_smtp_transport_parent_class)->connect (service, error))
+	if (!CAMEL_SERVICE_CLASS (camel_smtp_transport_parent_class)->
+		connect (service, cancellable, error))
 		return FALSE;
 
 	/* set some smtp transport defaults */
@@ -225,11 +165,15 @@ connect_to_server (CamelService *service,
 	camel_session_get_socks_proxy (session, &socks_host, &socks_port);
 
 	if (socks_host) {
-		camel_tcp_stream_set_socks_proxy ((CamelTcpStream *) tcp_stream, socks_host, socks_port);
+		camel_tcp_stream_set_socks_proxy (
+			CAMEL_TCP_STREAM (tcp_stream),
+			socks_host, socks_port);
 		g_free (socks_host);
 	}
 
-	if (camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, host, serv, fallback_port, error) == -1) {
+	if (camel_tcp_stream_connect (
+		CAMEL_TCP_STREAM (tcp_stream), host, serv,
+		fallback_port, cancellable, error) == -1) {
 		g_object_unref (tcp_stream);
 		return FALSE;
 	}
@@ -247,14 +191,16 @@ connect_to_server (CamelService *service,
 		/* Check for "220" */
 		g_free (respbuf);
 		respbuf = camel_stream_buffer_read_line (
-			CAMEL_STREAM_BUFFER (transport->istream), error);
+			CAMEL_STREAM_BUFFER (transport->istream),
+			cancellable, error);
 		if (respbuf == NULL) {
 			g_prefix_error (error, _("Welcome response error: "));
 			transport->connected = FALSE;
 			return FALSE;
 		}
 		if (strncmp (respbuf, "220", 3)) {
-			smtp_set_error (transport, respbuf, error);
+			smtp_set_error (
+				transport, respbuf, cancellable, error);
 			g_prefix_error (error, _("Welcome response error: "));
 			g_free (respbuf);
 			return FALSE;
@@ -264,7 +210,7 @@ connect_to_server (CamelService *service,
 
 	/* Try sending EHLO */
 	transport->flags |= CAMEL_SMTP_TRANSPORT_IS_ESMTP;
-	if (!smtp_helo (transport, error)) {
+	if (!smtp_helo (transport, cancellable, error)) {
 		if (!transport->connected)
 			return FALSE;
 
@@ -272,7 +218,7 @@ connect_to_server (CamelService *service,
 		g_clear_error (error);
 		transport->flags &= ~CAMEL_SMTP_TRANSPORT_IS_ESMTP;
 
-		if (!smtp_helo (transport, error)) {
+		if (!smtp_helo (transport, cancellable, error)) {
 			camel_service_disconnect ((CamelService *) transport, TRUE, NULL);
 
 			return FALSE;
@@ -298,7 +244,8 @@ connect_to_server (CamelService *service,
 	}
 
 	d(fprintf (stderr, "sending : STARTTLS\r\n"));
-	if (camel_stream_write (tcp_stream, "STARTTLS\r\n", 10, error) == -1) {
+	if (camel_stream_write (
+		tcp_stream, "STARTTLS\r\n", 10, cancellable, error) == -1) {
 		g_prefix_error (error, _("STARTTLS command failed: "));
 		goto exception_cleanup;
 	}
@@ -309,14 +256,16 @@ connect_to_server (CamelService *service,
 		/* Check for "220 Ready for TLS" */
 		g_free (respbuf);
 		respbuf = camel_stream_buffer_read_line (
-			CAMEL_STREAM_BUFFER (transport->istream), error);
+			CAMEL_STREAM_BUFFER (transport->istream),
+			cancellable, error);
 		if (respbuf == NULL) {
 			g_prefix_error (error, _("STARTTLS command failed: "));
 			transport->connected = FALSE;
 			goto exception_cleanup;
 		}
 		if (strncmp (respbuf, "220", 3) != 0) {
-			smtp_set_error (transport, respbuf, error);
+			smtp_set_error (
+				transport, respbuf, cancellable, error);
 			g_prefix_error (error, _("STARTTLS command failed: "));
 			g_free (respbuf);
 			goto exception_cleanup;
@@ -342,7 +291,7 @@ connect_to_server (CamelService *service,
 
 	/* We are supposed to re-EHLO after a successful STARTTLS to
            re-fetch any supported extensions. */
-	if (!smtp_helo (transport, error)) {
+	if (!smtp_helo (transport, cancellable, error)) {
 		camel_service_disconnect ((CamelService *) transport, TRUE, NULL);
 
 		return FALSE;
@@ -362,21 +311,9 @@ connect_to_server (CamelService *service,
 	return FALSE;
 }
 
-static struct {
-	const gchar *value;
-	const gchar *serv;
-	gint fallback_port;
-	gint mode;
-} ssl_options[] = {
-	{ "",              "smtps", SMTPS_PORT, MODE_SSL   },  /* really old (1.x) */
-	{ "always",        "smtps", SMTPS_PORT, MODE_SSL   },
-	{ "when-possible", "smtp",  SMTP_PORT, MODE_TLS   },
-	{ "never",         "smtp",  SMTP_PORT, MODE_CLEAR },
-	{ NULL,            "smtp",  SMTP_PORT, MODE_CLEAR },
-};
-
 static gboolean
 connect_to_server_wrapper (CamelService *service,
+                           GCancellable *cancellable,
                            GError **error)
 {
 	const gchar *ssl_mode;
@@ -403,11 +340,21 @@ connect_to_server_wrapper (CamelService *service,
 		fallback_port = 0;
 	}
 
-	return connect_to_server (service, service->url->host, serv, fallback_port, mode, error);
+	return connect_to_server (
+		service, service->url->host, serv,
+		fallback_port, mode, cancellable, error);
+}
+
+static void
+authtypes_free (gpointer key, gpointer value, gpointer data)
+{
+	g_free (value);
 }
 
 static gboolean
-smtp_connect (CamelService *service, GError **error)
+smtp_connect (CamelService *service,
+              GCancellable *cancellable,
+              GError **error)
 {
 	CamelSmtpTransport *transport = CAMEL_SMTP_TRANSPORT (service);
 	gboolean has_authtypes;
@@ -419,7 +366,7 @@ smtp_connect (CamelService *service, GError **error)
 		CamelSasl *sasl;
 
 		sasl = camel_sasl_new ("smtp", "POPB4SMTP", service);
-		chal = camel_sasl_challenge (sasl, NULL, error);
+		chal = camel_sasl_challenge (sasl, NULL, cancellable, error);
 		truth = camel_sasl_get_authenticated (sasl);
 		if (chal)
 			g_byte_array_free (chal, TRUE);
@@ -428,10 +375,10 @@ smtp_connect (CamelService *service, GError **error)
 		if (!truth)
 			return FALSE;
 
-		return connect_to_server_wrapper (service, error);
+		return connect_to_server_wrapper (service, cancellable, error);
 	}
 
-	if (!connect_to_server_wrapper (service, error))
+	if (!connect_to_server_wrapper (service, cancellable, error))
 		return FALSE;
 
 	/* check to see if AUTH is required, if so...then AUTH ourselves */
@@ -469,7 +416,8 @@ smtp_connect (CamelService *service, GError **error)
 			/* authentication mechanism doesn't need a password,
 			   so if it fails there's nothing we can do */
 			authenticated = smtp_auth (
-				transport, authtype->authproto, error);
+				transport, authtype->authproto,
+				cancellable, error);
 			if (!authenticated) {
 				camel_service_disconnect (service, TRUE, NULL);
 				return FALSE;
@@ -516,9 +464,10 @@ smtp_connect (CamelService *service, GError **error)
 			}
 
 			authenticated = smtp_auth (
-				transport, authtype->authproto, &local_error);
+				transport, authtype->authproto,
+				cancellable, &local_error);
 			if (!authenticated) {
-				if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ||
+				if (g_cancellable_is_cancelled (cancellable) ||
 				    g_error_matches (local_error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_UNAVAILABLE))
 					return FALSE;
 
@@ -543,15 +492,10 @@ smtp_connect (CamelService *service, GError **error)
 	return TRUE;
 }
 
-static void
-authtypes_free (gpointer key, gpointer value, gpointer data)
-{
-	g_free (value);
-}
-
 static gboolean
 smtp_disconnect (CamelService *service,
                  gboolean clean,
+                 GCancellable *cancellable,
                  GError **error)
 {
 	CamelServiceClass *service_class;
@@ -563,12 +507,12 @@ smtp_disconnect (CamelService *service,
 
 	if (transport->connected && clean) {
 		/* send the QUIT command to the SMTP server */
-		smtp_quit (transport, NULL);
+		smtp_quit (transport, cancellable, NULL);
 	}
 
 	/* Chain up to parent's disconnect() method. */
 	service_class = CAMEL_SERVICE_CLASS (camel_smtp_transport_parent_class);
-	if (!service_class->disconnect (service, clean, error))
+	if (!service_class->disconnect (service, clean, cancellable, error))
 		return FALSE;
 
 	if (transport->authtypes) {
@@ -595,54 +539,20 @@ smtp_disconnect (CamelService *service,
 	return TRUE;
 }
 
-static GHashTable *
-esmtp_get_authtypes (const guchar *buffer)
-{
-	const guchar *start, *end;
-	GHashTable *table = NULL;
-
-	/* advance to the first token */
-	start = buffer;
-	while (isspace ((gint) *start) || *start == '=')
-		start++;
-
-	if (!*start)
-		return NULL;
-
-	table = g_hash_table_new (g_str_hash, g_str_equal);
-
-	for (; *start; ) {
-		gchar *type;
-
-		/* advance to the end of the token */
-		end = start;
-		while (*end && !isspace ((gint) *end))
-			end++;
-
-		type = g_strndup ((gchar *) start, end - start);
-		g_hash_table_insert (table, type, type);
-
-		/* advance to the next token */
-		start = end;
-		while (isspace ((gint) *start))
-			start++;
-	}
-
-	return table;
-}
-
 static GList *
-query_auth_types (CamelService *service, GError **error)
+smtp_query_auth_types (CamelService *service,
+                       GCancellable *cancellable,
+                       GError **error)
 {
 	CamelSmtpTransport *transport = CAMEL_SMTP_TRANSPORT (service);
 	CamelServiceAuthType *authtype;
 	GList *types, *t, *next;
 
-	if (!connect_to_server_wrapper (service, error))
+	if (!connect_to_server_wrapper (service, cancellable, error))
 		return NULL;
 
 	if (!transport->authtypes) {
-		smtp_disconnect (service, TRUE, NULL);
+		smtp_disconnect (service, TRUE, cancellable, NULL);
 		return NULL;
 	}
 
@@ -657,26 +567,31 @@ query_auth_types (CamelService *service, GError **error)
 		}
 	}
 
-	smtp_disconnect (service, TRUE, NULL);
+	smtp_disconnect (service, TRUE, cancellable, NULL);
 
 	return types;
 }
 
 static gchar *
-get_name (CamelService *service, gboolean brief)
+smtp_get_name (CamelService *service, gboolean brief)
 {
 	if (brief)
-		return g_strdup_printf (_("SMTP server %s"), service->url->host);
-	else {
-		return g_strdup_printf (_("SMTP mail delivery via %s"),
-					service->url->host);
-	}
+		return g_strdup_printf (
+			_("SMTP server %s"),
+			service->url->host);
+	else
+		return g_strdup_printf (
+			_("SMTP mail delivery via %s"),
+			service->url->host);
 }
 
 static gboolean
-smtp_send_to (CamelTransport *transport, CamelMimeMessage *message,
-	      CamelAddress *from, CamelAddress *recipients,
-	      GError **error)
+smtp_send_to (CamelTransport *transport,
+              CamelMimeMessage *message,
+              CamelAddress *from,
+              CamelAddress *recipients,
+              GCancellable *cancellable,
+              GError **error)
 {
 	CamelSmtpTransport *smtp_transport = CAMEL_SMTP_TRANSPORT (transport);
 	CamelInternetAddress *cia;
@@ -699,15 +614,16 @@ smtp_send_to (CamelTransport *transport, CamelMimeMessage *message,
 		return FALSE;
 	}
 
-	camel_operation_start (NULL, _("Sending message"));
+	camel_operation_start (cancellable, _("Sending message"));
 
 	/* find out if the message has 8bit mime parts */
 	has_8bit_parts = camel_mime_message_has_8bit_parts (message);
 
 	/* rfc1652 (8BITMIME) requires that you notify the ESMTP daemon that
 	   you'll be sending an 8bit mime message at "MAIL FROM:" time. */
-	if (!smtp_mail (smtp_transport, addr, has_8bit_parts, error)) {
-		camel_operation_end (NULL);
+	if (!smtp_mail (
+		smtp_transport, addr, has_8bit_parts, cancellable, error)) {
+		camel_operation_end (cancellable);
 		return FALSE;
 	}
 
@@ -716,7 +632,7 @@ smtp_send_to (CamelTransport *transport, CamelMimeMessage *message,
 		g_set_error (
 			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
 			_("Cannot send message: no recipients defined."));
-		camel_operation_end (NULL);
+		camel_operation_end (cancellable);
 		return FALSE;
 	}
 
@@ -729,32 +645,160 @@ smtp_send_to (CamelTransport *transport, CamelMimeMessage *message,
 				error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
 				_("Cannot send message: "
 				  "one or more invalid recipients"));
-			camel_operation_end (NULL);
+			camel_operation_end (cancellable);
 			return FALSE;
 		}
 
 		enc = camel_internet_address_encode_address (NULL, NULL, addr);
-		if (!smtp_rcpt (smtp_transport, enc, error)) {
+		if (!smtp_rcpt (smtp_transport, enc, cancellable, error)) {
 			g_free (enc);
-			camel_operation_end (NULL);
+			camel_operation_end (cancellable);
 			return FALSE;
 		}
 		g_free (enc);
 	}
 
-	if (!smtp_data (smtp_transport, message, error)) {
-		camel_operation_end (NULL);
+	if (!smtp_data (smtp_transport, message, cancellable, error)) {
+		camel_operation_end (cancellable);
 		return FALSE;
 	}
 
 	/* reset the service for our next transfer session */
-	smtp_rset (smtp_transport, NULL);
+	smtp_rset (smtp_transport, cancellable, NULL);
 
-	camel_operation_end (NULL);
+	camel_operation_end (cancellable);
 
 	return TRUE;
 }
 
+static void
+camel_smtp_transport_class_init (CamelSmtpTransportClass *class)
+{
+	CamelTransportClass *transport_class;
+	CamelServiceClass *service_class;
+
+	service_class = CAMEL_SERVICE_CLASS (class);
+	service_class->connect = smtp_connect;
+	service_class->disconnect = smtp_disconnect;
+	service_class->query_auth_types = smtp_query_auth_types;
+	service_class->get_name = smtp_get_name;
+
+	transport_class = CAMEL_TRANSPORT_CLASS (class);
+	transport_class->send_to = smtp_send_to;
+}
+
+static void
+camel_smtp_transport_init (CamelSmtpTransport *smtp)
+{
+	smtp->flags = 0;
+	smtp->connected = FALSE;
+}
+
+static const gchar *
+smtp_error_string (gint error)
+{
+	/* SMTP error codes grabbed from rfc821 */
+	switch (error) {
+	case 0:
+		/* looks like a read problem, check errno */
+		if (errno)
+			return g_strerror (errno);
+		else
+			return _("Unknown");
+	case 500:
+		return _("Syntax error, command unrecognized");
+	case 501:
+		return _("Syntax error in parameters or arguments");
+	case 502:
+		return _("Command not implemented");
+	case 504:
+		return _("Command parameter not implemented");
+	case 211:
+		return _("System status, or system help reply");
+	case 214:
+		return _("Help message");
+	case 220:
+		return _("Service ready");
+	case 221:
+		return _("Service closing transmission channel");
+	case 421:
+		return _("Service not available, closing transmission channel");
+	case 250:
+		return _("Requested mail action okay, completed");
+	case 251:
+		return _("User not local; will forward to <forward-path>");
+	case 450:
+		return _("Requested mail action not taken: mailbox unavailable");
+	case 550:
+		return _("Requested action not taken: mailbox unavailable");
+	case 451:
+		return _("Requested action aborted: error in processing");
+	case 551:
+		return _("User not local; please try <forward-path>");
+	case 452:
+		return _("Requested action not taken: insufficient system storage");
+	case 552:
+		return _("Requested mail action aborted: exceeded storage allocation");
+	case 553:
+		return _("Requested action not taken: mailbox name not allowed");
+	case 354:
+		return _("Start mail input; end with <CRLF>.<CRLF>");
+	case 554:
+		return _("Transaction failed");
+
+	/* AUTH error codes: */
+	case 432:
+		return _("A password transition is needed");
+	case 534:
+		return _("Authentication mechanism is too weak");
+	case 538:
+		return _("Encryption required for requested authentication mechanism");
+	case 454:
+		return _("Temporary authentication failure");
+	case 530:
+		return _("Authentication required");
+
+	default:
+		return _("Unknown");
+	}
+}
+
+static GHashTable *
+esmtp_get_authtypes (const guchar *buffer)
+{
+	const guchar *start, *end;
+	GHashTable *table = NULL;
+
+	/* advance to the first token */
+	start = buffer;
+	while (isspace ((gint) *start) || *start == '=')
+		start++;
+
+	if (!*start)
+		return NULL;
+
+	table = g_hash_table_new (g_str_hash, g_str_equal);
+
+	for (; *start; ) {
+		gchar *type;
+
+		/* advance to the end of the token */
+		end = start;
+		while (*end && !isspace ((gint) *end))
+			end++;
+
+		type = g_strndup ((gchar *) start, end - start);
+		g_hash_table_insert (table, type, type);
+
+		/* advance to the next token */
+		start = end;
+		while (isspace ((gint) *start))
+			start++;
+	}
+
+	return table;
+}
+
 static const gchar *
 smtp_next_token (const gchar *buf)
 {
@@ -863,6 +907,7 @@ convert_to_local (GString *str)
 static void
 smtp_set_error (CamelSmtpTransport *transport,
                 const gchar *respbuf,
+                GCancellable *cancellable,
                 GError **error)
 {
 	const gchar *token, *rbuf = respbuf;
@@ -901,7 +946,8 @@ smtp_set_error (CamelSmtpTransport *transport,
 			if (*(rbuf + 3) == '-') {
 				g_free (buffer);
 				buffer = camel_stream_buffer_read_line (
-					CAMEL_STREAM_BUFFER (transport->istream), NULL);
+					CAMEL_STREAM_BUFFER (transport->istream),
+					cancellable, NULL);
 				g_string_append_c (string, '\n');
 			} else {
 				g_free (buffer);
@@ -944,7 +990,9 @@ smtp_set_error (CamelSmtpTransport *transport,
 }
 
 static gboolean
-smtp_helo (CamelSmtpTransport *transport, GError **error)
+smtp_helo (CamelSmtpTransport *transport,
+           GCancellable *cancellable,
+           GError **error)
 {
 	gchar *name = NULL, *cmdbuf = NULL, *respbuf = NULL;
 	const gchar *token, *numeric = NULL;
@@ -963,12 +1011,14 @@ smtp_helo (CamelSmtpTransport *transport, GError **error)
 		transport->authtypes = NULL;
 	}
 
-	camel_operation_start_transient (NULL, _("SMTP Greeting"));
+	camel_operation_start_transient (cancellable, _("SMTP Greeting"));
 
 	addr = transport->localaddr;
 	addrlen = transport->localaddrlen;
 
-	if (camel_getnameinfo (addr, addrlen, &name, NULL, NI_NUMERICHOST, NULL) != 0) {
+	if (camel_getnameinfo (
+		addr, addrlen, &name, NULL,
+		NI_NUMERICHOST, cancellable, NULL) != 0) {
 		name = g_strdup ("localhost.localdomain");
 	} else {
 		if (addr->sa_family == AF_INET6)
@@ -985,10 +1035,11 @@ smtp_helo (CamelSmtpTransport *transport, GError **error)
 	g_free (name);
 
 	d(fprintf (stderr, "sending : %s", cmdbuf));
-	if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf), error) == -1) {
+	if (camel_stream_write_string (
+		transport->ostream, cmdbuf, cancellable, error) == -1) {
 		g_free (cmdbuf);
 		g_prefix_error (error, _("HELO command failed: "));
-		camel_operation_end (NULL);
+		camel_operation_end (cancellable);
 
 		camel_service_disconnect ((CamelService *) transport, FALSE, NULL);
 
@@ -1000,17 +1051,19 @@ smtp_helo (CamelSmtpTransport *transport, GError **error)
 		/* Check for "250" */
 		g_free (respbuf);
 		respbuf = camel_stream_buffer_read_line (
-			CAMEL_STREAM_BUFFER (transport->istream), error);
+			CAMEL_STREAM_BUFFER (transport->istream),
+			cancellable, error);
 		if (respbuf == NULL) {
 			g_prefix_error (error, _("HELO command failed: "));
 			transport->connected = FALSE;
-			camel_operation_end (NULL);
+			camel_operation_end (cancellable);
 			return FALSE;
 		}
 		if (strncmp (respbuf, "250", 3)) {
-			smtp_set_error (transport, respbuf, error);
+			smtp_set_error (
+				transport, respbuf, cancellable, error);
 			g_prefix_error (error, _("HELO command failed: "));
-			camel_operation_end (NULL);
+			camel_operation_end (cancellable);
 			g_free (respbuf);
 			return FALSE;
 		}
@@ -1059,7 +1112,7 @@ smtp_helo (CamelSmtpTransport *transport, GError **error)
 	} while (*(respbuf+3) == '-'); /* if we got "250-" then loop again */
 	g_free (respbuf);
 
-	camel_operation_end (NULL);
+	camel_operation_end (cancellable);
 
 	return TRUE;
 }
@@ -1067,6 +1120,7 @@ smtp_helo (CamelSmtpTransport *transport, GError **error)
 static gboolean
 smtp_auth (CamelSmtpTransport *transport,
            const gchar *mech,
+           GCancellable *cancellable,
            GError **error)
 {
 	CamelService *service;
@@ -1076,18 +1130,19 @@ smtp_auth (CamelSmtpTransport *transport,
 
 	service = CAMEL_SERVICE (transport);
 
-	camel_operation_start_transient (NULL, _("SMTP Authentication"));
+	camel_operation_start_transient (cancellable, _("SMTP Authentication"));
 
 	sasl = camel_sasl_new ("smtp", mech, service);
 	if (!sasl) {
-		camel_operation_end (NULL);
+		camel_operation_end (cancellable);
 		g_set_error (
 			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
 			_("Error creating SASL authentication object."));
 		return FALSE;
 	}
 
-	challenge = camel_sasl_challenge_base64 (sasl, NULL, error);
+	challenge = camel_sasl_challenge_base64 (
+		sasl, NULL, cancellable, error);
 	if (challenge) {
 		auth_challenge = TRUE;
 		cmdbuf = g_strdup_printf ("AUTH %s %s\r\n", mech, challenge);
@@ -1097,7 +1152,9 @@ smtp_auth (CamelSmtpTransport *transport,
 	}
 
 	d(fprintf (stderr, "sending : %s", cmdbuf));
-	if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf), error) == -1) {
+	if (camel_stream_write_string (
+		transport->ostream, cmdbuf,
+		cancellable, error) == -1) {
 		g_free (cmdbuf);
 		g_prefix_error (error, _("AUTH command failed: "));
 		goto lose;
@@ -1105,7 +1162,8 @@ smtp_auth (CamelSmtpTransport *transport,
 	g_free (cmdbuf);
 
 	respbuf = camel_stream_buffer_read_line (
-		CAMEL_STREAM_BUFFER (transport->istream), error);
+		CAMEL_STREAM_BUFFER (transport->istream),
+		cancellable, error);
 
 	while (!camel_sasl_get_authenticated (sasl)) {
 		if (!respbuf) {
@@ -1116,7 +1174,8 @@ smtp_auth (CamelSmtpTransport *transport,
 
 		/* the server challenge/response should follow a 334 code */
 		if (strncmp (respbuf, "334", 3) != 0) {
-			smtp_set_error (transport, respbuf, error);
+			smtp_set_error (
+				transport, respbuf, cancellable, error);
 			g_prefix_error (error, _("AUTH command failed: "));
 			goto lose;
 		}
@@ -1133,7 +1192,8 @@ smtp_auth (CamelSmtpTransport *transport,
 		/* eat whtspc */
 		for (challenge = respbuf + 4; isspace (*challenge); challenge++);
 
-		challenge = camel_sasl_challenge_base64 (sasl, challenge, error);
+		challenge = camel_sasl_challenge_base64 (
+			sasl, challenge, cancellable, error);
 		if (challenge == NULL)
 			goto break_and_lose;
 
@@ -1143,7 +1203,9 @@ smtp_auth (CamelSmtpTransport *transport,
 		cmdbuf = g_strdup_printf ("%s\r\n", challenge);
 		g_free (challenge);
 		d(fprintf (stderr, "sending : %s", cmdbuf));
-		if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf), error) == -1) {
+		if (camel_stream_write_string (
+			transport->ostream, cmdbuf,
+			cancellable, error) == -1) {
 			g_free (cmdbuf);
 			goto lose;
 		}
@@ -1151,7 +1213,8 @@ smtp_auth (CamelSmtpTransport *transport,
 
 		/* get the server's response */
 		respbuf = camel_stream_buffer_read_line (
-			CAMEL_STREAM_BUFFER (transport->istream), error);
+			CAMEL_STREAM_BUFFER (transport->istream),
+			cancellable, error);
 	}
 
 	if (respbuf == NULL)
@@ -1178,7 +1241,7 @@ smtp_auth (CamelSmtpTransport *transport,
 	}
 
 	g_object_unref (sasl);
-	camel_operation_end (NULL);
+	camel_operation_end (cancellable);
 
 	g_free (respbuf);
 
@@ -1187,14 +1250,14 @@ smtp_auth (CamelSmtpTransport *transport,
  break_and_lose:
 	/* Get the server out of "waiting for continuation data" mode. */
 	d(fprintf (stderr, "sending : *\n"));
-	camel_stream_write (transport->ostream, "*\r\n", 3, NULL);
+	camel_stream_write (transport->ostream, "*\r\n", 3, cancellable, NULL);
 	respbuf = camel_stream_buffer_read_line (
-		CAMEL_STREAM_BUFFER (transport->istream), NULL);
+		CAMEL_STREAM_BUFFER (transport->istream), cancellable, NULL);
 	d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
 
  lose:
 	g_object_unref (sasl);
-	camel_operation_end (NULL);
+	camel_operation_end (cancellable);
 
 	g_free (respbuf);
 
@@ -1202,7 +1265,11 @@ smtp_auth (CamelSmtpTransport *transport,
 }
 
 static gboolean
-smtp_mail (CamelSmtpTransport *transport, const gchar *sender, gboolean has_8bit_parts, GError **error)
+smtp_mail (CamelSmtpTransport *transport,
+           const gchar *sender,
+           gboolean has_8bit_parts,
+           GCancellable *cancellable,
+           GError **error)
 {
 	/* we gotta tell the smtp server who we are. (our email addy) */
 	gchar *cmdbuf, *respbuf = NULL;
@@ -1214,7 +1281,8 @@ smtp_mail (CamelSmtpTransport *transport, const gchar *sender, gboolean has_8bit
 
 	d(fprintf (stderr, "sending : %s", cmdbuf));
 
-	if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf), error) == -1) {
+	if (camel_stream_write_string (
+		transport->ostream, cmdbuf, cancellable, error) == -1) {
 		g_free (cmdbuf);
 		g_prefix_error (error, _("MAIL FROM command failed: "));
 		camel_service_disconnect ((CamelService *) transport, FALSE, NULL);
@@ -1226,7 +1294,8 @@ smtp_mail (CamelSmtpTransport *transport, const gchar *sender, gboolean has_8bit
 		/* Check for "250 Sender OK..." */
 		g_free (respbuf);
 		respbuf = camel_stream_buffer_read_line (
-			CAMEL_STREAM_BUFFER (transport->istream), error);
+			CAMEL_STREAM_BUFFER (transport->istream),
+			cancellable, error);
 		if (respbuf == NULL) {
 			g_prefix_error (error, _("MAIL FROM command failed: "));
 			camel_service_disconnect (
@@ -1234,8 +1303,10 @@ smtp_mail (CamelSmtpTransport *transport, const gchar *sender, gboolean has_8bit
 			return FALSE;
 		}
 		if (strncmp (respbuf, "250", 3)) {
-			smtp_set_error (transport, respbuf, error);
-			g_prefix_error (error, _("MAIL FROM command failed: "));
+			smtp_set_error (
+				transport, respbuf, cancellable, error);
+			g_prefix_error (
+				error, _("MAIL FROM command failed: "));
 			g_free (respbuf);
 			return FALSE;
 		}
@@ -1246,7 +1317,10 @@ smtp_mail (CamelSmtpTransport *transport, const gchar *sender, gboolean has_8bit
 }
 
 static gboolean
-smtp_rcpt (CamelSmtpTransport *transport, const gchar *recipient, GError **error)
+smtp_rcpt (CamelSmtpTransport *transport,
+           const gchar *recipient,
+           GCancellable *cancellable,
+           GError **error)
 {
 	/* we gotta tell the smtp server who we are going to be sending
 	 * our email to */
@@ -1256,7 +1330,8 @@ smtp_rcpt (CamelSmtpTransport *transport, const gchar *recipient, GError **error
 
 	d(fprintf (stderr, "sending : %s", cmdbuf));
 
-	if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf), error) == -1) {
+	if (camel_stream_write_string (
+		transport->ostream, cmdbuf, cancellable, error) == -1) {
 		g_free (cmdbuf);
 		g_prefix_error (error, _("RCPT TO command failed: "));
 		camel_service_disconnect ((CamelService *) transport, FALSE, NULL);
@@ -1269,7 +1344,8 @@ smtp_rcpt (CamelSmtpTransport *transport, const gchar *recipient, GError **error
 		/* Check for "250 Recipient OK..." */
 		g_free (respbuf);
 		respbuf = camel_stream_buffer_read_line (
-			CAMEL_STREAM_BUFFER (transport->istream), error);
+			CAMEL_STREAM_BUFFER (transport->istream),
+			cancellable, error);
 		if (respbuf == NULL) {
 			g_prefix_error (
 				error, _("RCPT TO <%s> failed: "), recipient);
@@ -1278,7 +1354,8 @@ smtp_rcpt (CamelSmtpTransport *transport, const gchar *recipient, GError **error
 			return FALSE;
 		}
 		if (strncmp (respbuf, "250", 3)) {
-			smtp_set_error (transport, respbuf, error);
+			smtp_set_error (
+				transport, respbuf, cancellable, error);
 			g_prefix_error (
 				error, _("RCPT TO <%s> failed: "), recipient);
 			g_free (respbuf);
@@ -1292,7 +1369,10 @@ smtp_rcpt (CamelSmtpTransport *transport, const gchar *recipient, GError **error
 }
 
 static gboolean
-smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, GError **error)
+smtp_data (CamelSmtpTransport *transport,
+           CamelMimeMessage *message,
+           GCancellable *cancellable,
+           GError **error)
 {
 	struct _camel_header_raw *header, *savedbcc, *n, *tail;
 	CamelBestencEncoding enctype = CAMEL_BESTENC_8BIT;
@@ -1316,7 +1396,8 @@ smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, GError **er
 
 	d(fprintf (stderr, "sending : %s", cmdbuf));
 
-	if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf), error) == -1) {
+	if (camel_stream_write_string (
+		transport->ostream, cmdbuf, cancellable, error) == -1) {
 		g_free (cmdbuf);
 		g_prefix_error (error, _("DATA command failed: "));
 		camel_service_disconnect ((CamelService *) transport, FALSE, NULL);
@@ -1325,7 +1406,7 @@ smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, GError **er
 	g_free (cmdbuf);
 
 	respbuf = camel_stream_buffer_read_line (
-		CAMEL_STREAM_BUFFER (transport->istream), error);
+		CAMEL_STREAM_BUFFER (transport->istream), cancellable, error);
 	if (respbuf == NULL) {
 		g_prefix_error (error, _("DATA command failed: "));
 		camel_service_disconnect (
@@ -1336,7 +1417,7 @@ smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, GError **er
 		/* We should have gotten instructions on how to use the DATA
 		 * command: 354 Enter mail, end with "." on a line by itself
 		 */
-		smtp_set_error (transport, respbuf, error);
+		smtp_set_error (transport, respbuf, cancellable, error);
 		g_prefix_error (error, _("DATA command failed: "));
 		g_free (respbuf);
 		return FALSE;
@@ -1367,12 +1448,13 @@ smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, GError **er
 	/* find out how large the message is... */
 	null = CAMEL_STREAM_NULL (camel_stream_null_new ());
 	camel_data_wrapper_write_to_stream (
-		CAMEL_DATA_WRAPPER (message), CAMEL_STREAM (null), NULL);
+		CAMEL_DATA_WRAPPER (message),
+		CAMEL_STREAM (null), NULL, NULL);
 
 	filtered_stream = camel_stream_filter_new (transport->ostream);
 
 	/* setup progress reporting for message sending... */
-	filter = camel_mime_filter_progress_new (NULL, null->written);
+	filter = camel_mime_filter_progress_new (cancellable, null->written);
 	camel_stream_filter_add (
 		CAMEL_STREAM_FILTER (filtered_stream), filter);
 	g_object_unref (filter);
@@ -1388,7 +1470,8 @@ smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, GError **er
 
 	/* write the message */
 	ret = camel_data_wrapper_write_to_stream (
-		CAMEL_DATA_WRAPPER (message), filtered_stream, error);
+		CAMEL_DATA_WRAPPER (message),
+		filtered_stream, cancellable, error);
 
 	/* restore the bcc headers */
 	header->next = savedbcc;
@@ -1402,14 +1485,16 @@ smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, GError **er
 		return FALSE;
 	}
 
-	camel_stream_flush (filtered_stream, NULL);
+	camel_stream_flush (filtered_stream, cancellable, NULL);
 	g_object_unref (filtered_stream);
 
 	/* terminate the message body */
 
 	d(fprintf (stderr, "sending : \\r\\n.\\r\\n\n"));
 
-	if (camel_stream_write (transport->ostream, "\r\n.\r\n", 5, error) == -1) {
+	if (camel_stream_write (
+		transport->ostream, "\r\n.\r\n", 5,
+		cancellable, error) == -1) {
 		g_prefix_error (error, _("DATA command failed: "));
 		camel_service_disconnect ((CamelService *) transport, FALSE, NULL);
 		return FALSE;
@@ -1419,7 +1504,8 @@ smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, GError **er
 		/* Check for "250 Sender OK..." */
 		g_free (respbuf);
 		respbuf = camel_stream_buffer_read_line (
-			CAMEL_STREAM_BUFFER (transport->istream), error);
+			CAMEL_STREAM_BUFFER (transport->istream),
+			cancellable, error);
 		if (respbuf == NULL) {
 			g_prefix_error (error, _("DATA command failed: "));
 			camel_service_disconnect (
@@ -1427,7 +1513,8 @@ smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, GError **er
 			return FALSE;
 		}
 		if (strncmp (respbuf, "250", 3) != 0) {
-			smtp_set_error (transport, respbuf, error);
+			smtp_set_error (
+				transport, respbuf, cancellable, error);
 			g_prefix_error (error, _("DATA command failed: "));
 			g_free (respbuf);
 			return FALSE;
@@ -1439,7 +1526,9 @@ smtp_data (CamelSmtpTransport *transport, CamelMimeMessage *message, GError **er
 }
 
 static gboolean
-smtp_rset (CamelSmtpTransport *transport, GError **error)
+smtp_rset (CamelSmtpTransport *transport,
+           GCancellable *cancellable,
+           GError **error)
 {
 	/* we are going to reset the smtp server (just to be nice) */
 	gchar *cmdbuf, *respbuf = NULL;
@@ -1448,7 +1537,8 @@ smtp_rset (CamelSmtpTransport *transport, GError **error)
 
 	d(fprintf (stderr, "sending : %s", cmdbuf));
 
-	if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf), error) == -1) {
+	if (camel_stream_write_string (
+		transport->ostream, cmdbuf, cancellable, error) == -1) {
 		g_free (cmdbuf);
 		g_prefix_error (error, _("RSET command failed: "));
 		camel_service_disconnect ((CamelService *) transport, FALSE, NULL);
@@ -1460,7 +1550,8 @@ smtp_rset (CamelSmtpTransport *transport, GError **error)
 		/* Check for "250" */
 		g_free (respbuf);
 		respbuf = camel_stream_buffer_read_line (
-			CAMEL_STREAM_BUFFER (transport->istream), error);
+			CAMEL_STREAM_BUFFER (transport->istream),
+			cancellable, error);
 		if (respbuf == NULL) {
 			g_prefix_error (error, _("RSET command failed: "));
 			camel_service_disconnect (
@@ -1468,7 +1559,8 @@ smtp_rset (CamelSmtpTransport *transport, GError **error)
 			return FALSE;
 		}
 		if (strncmp (respbuf, "250", 3) != 0) {
-			smtp_set_error (transport, respbuf, error);
+			smtp_set_error (
+				transport, respbuf, cancellable, error);
 			g_prefix_error (error, _("RSET command failed: "));
 			g_free (respbuf);
 			return FALSE;
@@ -1480,7 +1572,9 @@ smtp_rset (CamelSmtpTransport *transport, GError **error)
 }
 
 static gboolean
-smtp_quit (CamelSmtpTransport *transport, GError **error)
+smtp_quit (CamelSmtpTransport *transport,
+           GCancellable *cancellable,
+           GError **error)
 {
 	/* we are going to reset the smtp server (just to be nice) */
 	gchar *cmdbuf, *respbuf = NULL;
@@ -1489,7 +1583,8 @@ smtp_quit (CamelSmtpTransport *transport, GError **error)
 
 	d(fprintf (stderr, "sending : %s", cmdbuf));
 
-	if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf), error) == -1) {
+	if (camel_stream_write_string (
+		transport->ostream, cmdbuf, cancellable, error) == -1) {
 		g_free (cmdbuf);
 		g_prefix_error (error, _("QUIT command failed: "));
 		return FALSE;
@@ -1500,7 +1595,8 @@ smtp_quit (CamelSmtpTransport *transport, GError **error)
 		/* Check for "221" */
 		g_free (respbuf);
 		respbuf = camel_stream_buffer_read_line (
-			CAMEL_STREAM_BUFFER (transport->istream), error);
+			CAMEL_STREAM_BUFFER (transport->istream),
+			cancellable, error);
 
 		d(fprintf (stderr, "received: %s\n", respbuf ? respbuf : "(null)"));
 		if (respbuf == NULL) {
@@ -1509,7 +1605,8 @@ smtp_quit (CamelSmtpTransport *transport, GError **error)
 			return FALSE;
 		}
 		if (strncmp (respbuf, "221", 3) != 0) {
-			smtp_set_error (transport, respbuf, error);
+			smtp_set_error (
+				transport, respbuf, cancellable, error);
 			g_prefix_error (error, _("QUIT command failed: "));
 			g_free (respbuf);
 			return FALSE;
diff --git a/docs/reference/camel/tmpl/camel-cipher-context.sgml b/docs/reference/camel/tmpl/camel-cipher-context.sgml
index a6343eb..768a8a6 100644
--- a/docs/reference/camel/tmpl/camel-cipher-context.sgml
+++ b/docs/reference/camel/tmpl/camel-cipher-context.sgml
@@ -146,6 +146,7 @@ CamelCipherContext
 @hash: 
 @ipart: 
 @opart: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -157,6 +158,7 @@ CamelCipherContext
 
 @context: 
 @ipart: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -171,6 +173,7 @@ CamelCipherContext
 @recipients: 
 @ipart: 
 @opart: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -183,6 +186,7 @@ CamelCipherContext
 @context: 
 @ipart: 
 @opart: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -194,6 +198,7 @@ CamelCipherContext
 
 @context: 
 @istream: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -206,6 +211,7 @@ CamelCipherContext
 @context: 
 @keys: 
 @ostream: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -480,6 +486,20 @@ CamelCipherContext
 @gpointer cert_data: 
 @gpointer cert_data:
 @gpointer cert_data: 
+ gpointer cert_data:
+ gpointer cert_data: 
+ gpointer cert_data:
+ gpointer cert_data: 
+ gpointer cert_data:
+ gpointer cert_data: 
+ gpointer cert_data:
+ gpointer cert_data: 
+ gpointer cert_data:
+ gpointer cert_data: 
+ gpointer cert_data:
+ gpointer cert_data: 
+ gpointer cert_data:
+ gpointer cert_data: 
 @gpointer cert_data: 
 
 
@@ -508,6 +528,7 @@ CamelCipherContext
 @part: 
 @flags: 
 @ostream: 
+ cancellable: 
 @error: 
 @Returns: 
 
diff --git a/docs/reference/camel/tmpl/camel-data-wrapper.sgml b/docs/reference/camel/tmpl/camel-data-wrapper.sgml
index b75b0a4..499158e 100644
--- a/docs/reference/camel/tmpl/camel-data-wrapper.sgml
+++ b/docs/reference/camel/tmpl/camel-data-wrapper.sgml
@@ -42,6 +42,7 @@ CamelDataWrapper
 
 @data_wrapper: 
 @stream: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -53,6 +54,7 @@ CamelDataWrapper
 
 @data_wrapper: 
 @stream: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -100,6 +102,7 @@ CamelDataWrapper
 
 @data_wrapper: 
 @stream: 
+ cancellable: 
 @error: 
 @Returns: 
 
diff --git a/docs/reference/camel/tmpl/camel-disco-diary.sgml b/docs/reference/camel/tmpl/camel-disco-diary.sgml
index f9bd316..2f8be84 100644
--- a/docs/reference/camel/tmpl/camel-disco-diary.sgml
+++ b/docs/reference/camel/tmpl/camel-disco-diary.sgml
@@ -72,6 +72,7 @@ CamelDiscoDiary
 </para>
 
 @diary: 
+ cancellable: 
 @error: 
 
 
diff --git a/docs/reference/camel/tmpl/camel-disco-folder.sgml b/docs/reference/camel/tmpl/camel-disco-folder.sgml
index db6605d..4bd260d 100644
--- a/docs/reference/camel/tmpl/camel-disco-folder.sgml
+++ b/docs/reference/camel/tmpl/camel-disco-folder.sgml
@@ -56,6 +56,7 @@ CamelDiscoFolder
 
 @folder: 
 @uids: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -67,6 +68,7 @@ CamelDiscoFolder
 
 @disco_folder: 
 @uid: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -78,6 +80,7 @@ CamelDiscoFolder
 
 @disco_folder: 
 @expression: 
+ cancellable: 
 @error: 
 @Returns: 
 
diff --git a/docs/reference/camel/tmpl/camel-disco-store.sgml b/docs/reference/camel/tmpl/camel-disco-store.sgml
index d33bc16..1f80692 100644
--- a/docs/reference/camel/tmpl/camel-disco-store.sgml
+++ b/docs/reference/camel/tmpl/camel-disco-store.sgml
@@ -51,6 +51,7 @@ CamelDiscoStore
 
 @store: 
 @status: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -80,6 +81,7 @@ CamelDiscoStore
 </para>
 
 @store: 
+ cancellable: 
 @error: 
 
 
diff --git a/docs/reference/camel/tmpl/camel-file-utils.sgml b/docs/reference/camel/tmpl/camel-file-utils.sgml
index a4780e6..9069ab4 100644
--- a/docs/reference/camel/tmpl/camel-file-utils.sgml
+++ b/docs/reference/camel/tmpl/camel-file-utils.sgml
@@ -186,6 +186,7 @@ camel-file-utils
 @fd: 
 @buf: 
 @n: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -198,6 +199,7 @@ camel-file-utils
 @fd: 
 @buf: 
 @n: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -210,6 +212,7 @@ camel-file-utils
 @fd: 
 @buf: 
 @n: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -222,6 +225,7 @@ camel-file-utils
 @fd: 
 @buf: 
 @n: 
+ cancellable: 
 @error: 
 @Returns: 
 
diff --git a/docs/reference/camel/tmpl/camel-filter-driver.sgml b/docs/reference/camel/tmpl/camel-filter-driver.sgml
index dd2cb2c..d46023b 100644
--- a/docs/reference/camel/tmpl/camel-filter-driver.sgml
+++ b/docs/reference/camel/tmpl/camel-filter-driver.sgml
@@ -157,6 +157,7 @@ CamelFilterDriver
 @source: 
 @source_url: 
 @original_source_url: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -169,6 +170,7 @@ CamelFilterDriver
 @driver: 
 @mbox: 
 @original_source_url: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -183,6 +185,7 @@ CamelFilterDriver
 @cache: 
 @uids: 
 @remove: 
+ cancellable: 
 @error: 
 @Returns: 
 
diff --git a/docs/reference/camel/tmpl/camel-folder.sgml b/docs/reference/camel/tmpl/camel-folder.sgml
index 147dcde..e337f03 100644
--- a/docs/reference/camel/tmpl/camel-folder.sgml
+++ b/docs/reference/camel/tmpl/camel-folder.sgml
@@ -166,6 +166,7 @@ CamelFolder
 </para>
 
 @folder: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -177,6 +178,7 @@ CamelFolder
 
 @folder: 
 @expunge: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -205,6 +207,7 @@ CamelFolder
 </para>
 
 @folder: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -347,6 +350,7 @@ CamelFolder
 @message: 
 @info: 
 @appended_uid: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -412,6 +416,7 @@ CamelFolder
 
 @folder: 
 @uid: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -423,6 +428,7 @@ CamelFolder
 
 @folder: 
 @uid: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -575,6 +581,7 @@ CamelFolder
 @dest: 
 @transferred_uids: 
 @delete_originals: 
+ cancellable: 
 @error: 
 @Returns: 
 
diff --git a/docs/reference/camel/tmpl/camel-mime-filter-progress.sgml b/docs/reference/camel/tmpl/camel-mime-filter-progress.sgml
index ab2d1f1..b115427 100644
--- a/docs/reference/camel/tmpl/camel-mime-filter-progress.sgml
+++ b/docs/reference/camel/tmpl/camel-mime-filter-progress.sgml
@@ -31,7 +31,7 @@ CamelMimeFilterProgress
 
 </para>
 
- operation: 
+ cancellable: 
 @total: 
 @Returns: 
 
diff --git a/docs/reference/camel/tmpl/camel-mime-part.sgml b/docs/reference/camel/tmpl/camel-mime-part.sgml
index 26bb04a..4083d8b 100644
--- a/docs/reference/camel/tmpl/camel-mime-part.sgml
+++ b/docs/reference/camel/tmpl/camel-mime-part.sgml
@@ -233,6 +233,7 @@ CamelMimePart
 
 @mime_part: 
 @parser: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -264,6 +265,7 @@ CamelMimePart
 
 @mime_part: 
 @mp: 
+ cancellable: 
 @error: 
 @Returns: 
 
diff --git a/docs/reference/camel/tmpl/camel-net-utils.sgml b/docs/reference/camel/tmpl/camel-net-utils.sgml
index 1463976..5ed463c 100644
--- a/docs/reference/camel/tmpl/camel-net-utils.sgml
+++ b/docs/reference/camel/tmpl/camel-net-utils.sgml
@@ -161,6 +161,7 @@ camel-net-utils
 @name: 
 @service: 
 @hints: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -183,6 +184,7 @@ camel-net-utils
 @host: 
 @serv: 
 @flags: 
+ cancellable: 
 @error: 
 @Returns: 
 
diff --git a/docs/reference/camel/tmpl/camel-offline-folder.sgml b/docs/reference/camel/tmpl/camel-offline-folder.sgml
index 87b2b59..81ba68e 100644
--- a/docs/reference/camel/tmpl/camel-offline-folder.sgml
+++ b/docs/reference/camel/tmpl/camel-offline-folder.sgml
@@ -56,6 +56,7 @@ CamelOfflineFolder
 
 @offline: 
 @expression: 
+ cancellable: 
 @error: 
 @Returns: 
 
diff --git a/docs/reference/camel/tmpl/camel-offline-journal.sgml b/docs/reference/camel/tmpl/camel-offline-journal.sgml
index 1ed0a27..6274a7e 100644
--- a/docs/reference/camel/tmpl/camel-offline-journal.sgml
+++ b/docs/reference/camel/tmpl/camel-offline-journal.sgml
@@ -67,6 +67,7 @@ CamelOfflineJournal
 </para>
 
 @journal: 
+ cancellable: 
 @error: 
 @Returns: 
 
diff --git a/docs/reference/camel/tmpl/camel-offline-store.sgml b/docs/reference/camel/tmpl/camel-offline-store.sgml
index 4a1f37b..592e59e 100644
--- a/docs/reference/camel/tmpl/camel-offline-store.sgml
+++ b/docs/reference/camel/tmpl/camel-offline-store.sgml
@@ -33,6 +33,7 @@ CamelOfflineStore
 
 @store: 
 @state: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -53,6 +54,7 @@ CamelOfflineStore
 </para>
 
 @store: 
+ cancellable: 
 @error: 
 @Returns: 
 
diff --git a/docs/reference/camel/tmpl/camel-operation.sgml b/docs/reference/camel/tmpl/camel-operation.sgml
index a2fdedc..3660bc7 100644
--- a/docs/reference/camel/tmpl/camel-operation.sgml
+++ b/docs/reference/camel/tmpl/camel-operation.sgml
@@ -53,23 +53,6 @@ camel-operation
 @operation: 
 
 
-<!-- ##### FUNCTION camel_operation_register ##### -->
-<para>
-
-</para>
-
- operation: 
- Returns: 
-
-
-<!-- ##### FUNCTION camel_operation_unregister ##### -->
-<para>
-
-</para>
-
- void: 
-
-
 <!-- ##### FUNCTION camel_operation_cancel_check ##### -->
 <para>
 
@@ -97,21 +80,12 @@ camel-operation
 @Returns: 
 
 
-<!-- ##### FUNCTION camel_operation_registered ##### -->
-<para>
-
-</para>
-
- void: 
- Returns: 
-
-
 <!-- ##### FUNCTION camel_operation_start ##### -->
 <para>
 
 </para>
 
- cc: 
+ cancellable: 
 @what: 
 @Varargs: 
 
@@ -121,7 +95,7 @@ camel-operation
 
 </para>
 
- cc: 
+ cancellable: 
 @what: 
 @Varargs: 
 
@@ -131,7 +105,7 @@ camel-operation
 
 </para>
 
- operation: 
+ cancellable: 
 @pc: 
 
 
@@ -140,6 +114,6 @@ camel-operation
 
 </para>
 
- operation: 
+ cancellable: 
 
 
diff --git a/docs/reference/camel/tmpl/camel-sasl.sgml b/docs/reference/camel/tmpl/camel-sasl.sgml
index 2a7e348..a855001 100644
--- a/docs/reference/camel/tmpl/camel-sasl.sgml
+++ b/docs/reference/camel/tmpl/camel-sasl.sgml
@@ -53,6 +53,7 @@ CamelSasl
 
 @sasl: 
 @token: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -64,6 +65,7 @@ CamelSasl
 
 @sasl: 
 @token: 
+ cancellable: 
 @error: 
 @Returns: 
 
diff --git a/docs/reference/camel/tmpl/camel-service.sgml b/docs/reference/camel/tmpl/camel-service.sgml
index 1d809ec..7120ef6 100644
--- a/docs/reference/camel/tmpl/camel-service.sgml
+++ b/docs/reference/camel/tmpl/camel-service.sgml
@@ -158,6 +158,7 @@ CamelService
 </para>
 
 @service: 
+ cancellable: 
 @error: 
 @Returns: 
 
diff --git a/docs/reference/camel/tmpl/camel-session.sgml b/docs/reference/camel/tmpl/camel-session.sgml
index f8ed9ee..7070939 100644
--- a/docs/reference/camel/tmpl/camel-session.sgml
+++ b/docs/reference/camel/tmpl/camel-session.sgml
@@ -76,7 +76,7 @@ CamelSession
 @id: 
 @error: 
 @ops: 
- op: 
+ cancellable: 
 @session: 
 @data: 
 
diff --git a/docs/reference/camel/tmpl/camel-store.sgml b/docs/reference/camel/tmpl/camel-store.sgml
index 64e1e98..f9b7aea 100644
--- a/docs/reference/camel/tmpl/camel-store.sgml
+++ b/docs/reference/camel/tmpl/camel-store.sgml
@@ -379,6 +379,7 @@ CamelStore
 @store: 
 @folder_name: 
 @flags: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -389,6 +390,7 @@ CamelStore
 </para>
 
 @store: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -399,6 +401,7 @@ CamelStore
 </para>
 
 @store: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -409,6 +412,7 @@ CamelStore
 </para>
 
 @store: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -421,6 +425,7 @@ CamelStore
 @store: 
 @parent_name: 
 @folder_name: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -432,6 +437,7 @@ CamelStore
 
 @store: 
 @folder_name: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -444,6 +450,7 @@ CamelStore
 @store: 
 @old_namein: 
 @new_name: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -501,6 +508,7 @@ CamelStore
 
 @store: 
 @expunge: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -513,6 +521,7 @@ CamelStore
 @store: 
 @top: 
 @flags: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -608,6 +617,7 @@ CamelStore
 
 @store: 
 @folder_name: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -619,6 +629,7 @@ CamelStore
 
 @store: 
 @folder_name: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -629,6 +640,7 @@ CamelStore
 </para>
 
 @store: 
+ cancellable: 
 @error: 
 @Returns: 
 
diff --git a/docs/reference/camel/tmpl/camel-stream-buffer.sgml b/docs/reference/camel/tmpl/camel-stream-buffer.sgml
index 12206f4..48955a1 100644
--- a/docs/reference/camel/tmpl/camel-stream-buffer.sgml
+++ b/docs/reference/camel/tmpl/camel-stream-buffer.sgml
@@ -67,6 +67,7 @@ CamelStreamBuffer
 @sbf: 
 @buf: 
 @max: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -77,6 +78,7 @@ CamelStreamBuffer
 </para>
 
 @sbf: 
+ cancellable: 
 @error: 
 @Returns: 
 
diff --git a/docs/reference/camel/tmpl/camel-stream.sgml b/docs/reference/camel/tmpl/camel-stream.sgml
index ca4f3c8..e7dea6b 100644
--- a/docs/reference/camel/tmpl/camel-stream.sgml
+++ b/docs/reference/camel/tmpl/camel-stream.sgml
@@ -34,6 +34,7 @@ CamelStream
 @stream: 
 @buffer: 
 @n: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -46,6 +47,7 @@ CamelStream
 @stream: 
 @buffer: 
 @n: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -56,6 +58,7 @@ CamelStream
 </para>
 
 @stream: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -66,6 +69,7 @@ CamelStream
 </para>
 
 @stream: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -96,6 +100,7 @@ CamelStream
 
 @stream: 
 @string: 
+ cancellable: 
 @error: 
 @Returns: 
 
@@ -129,6 +134,7 @@ CamelStream
 
 @stream: 
 @output_stream: 
+ cancellable: 
 @error: 
 @Returns: 
 
diff --git a/docs/reference/camel/tmpl/camel-tcp-stream.sgml b/docs/reference/camel/tmpl/camel-tcp-stream.sgml
index b15841d..69d4ba8 100644
--- a/docs/reference/camel/tmpl/camel-tcp-stream.sgml
+++ b/docs/reference/camel/tmpl/camel-tcp-stream.sgml
@@ -71,6 +71,7 @@ CamelTcpStream
 @host: 
 @service: 
 @fallback_port: 
+ cancellable: 
 @error: 
 @Returns: 
 
diff --git a/docs/reference/camel/tmpl/camel-transport.sgml b/docs/reference/camel/tmpl/camel-transport.sgml
index 04e6225..9efc6e7 100644
--- a/docs/reference/camel/tmpl/camel-transport.sgml
+++ b/docs/reference/camel/tmpl/camel-transport.sgml
@@ -35,6 +35,7 @@ CamelTransport
 @message: 
 @from: 
 @recipients: 
+ cancellable: 
 @error: 
 @Returns: 
 
diff --git a/docs/reference/camel/tmpl/camel-unused.sgml b/docs/reference/camel/tmpl/camel-unused.sgml
index 5f8af4f..fff8076 100644
--- a/docs/reference/camel/tmpl/camel-unused.sgml
+++ b/docs/reference/camel/tmpl/camel-unused.sgml
@@ -7318,6 +7318,22 @@ streams
 
 @cc: 
 
+<!-- ##### FUNCTION camel_operation_register ##### -->
+<para>
+
+</para>
+
+ operation: 
+ Returns: 
+
+<!-- ##### FUNCTION camel_operation_registered ##### -->
+<para>
+
+</para>
+
+ void: 
+ Returns: 
+
 <!-- ##### ENUM camel_operation_status_t ##### -->
 <para>
 
@@ -7333,6 +7349,13 @@ streams
 
 @cc: 
 
+<!-- ##### FUNCTION camel_operation_unregister ##### -->
+<para>
+
+</para>
+
+ void: 
+
 <!-- ##### FUNCTION camel_partition_table_get_type ##### -->
 <para>
 



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