Fix memory leak in create_msg_thread()
[modest] / src / modest-mail-operation.c
index bb0019d..7c78ded 100644 (file)
@@ -388,6 +388,8 @@ void
 modest_mail_operation_execute_error_handler (ModestMailOperation *self)
 {
        ModestMailOperationPrivate *priv;
+
+       g_return_if_fail (self && MODEST_IS_MAIL_OPERATION(self));
        
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
        g_return_if_fail(priv->status != MODEST_MAIL_OPERATION_STATUS_SUCCESS);     
@@ -403,6 +405,9 @@ modest_mail_operation_get_type_operation (ModestMailOperation *self)
 {
        ModestMailOperationPrivate *priv;
 
+       g_return_val_if_fail (self && MODEST_IS_MAIL_OPERATION(self),
+                             MODEST_MAIL_OPERATION_TYPE_UNKNOWN);
+       
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
        
        return priv->op_type;
@@ -414,6 +419,9 @@ modest_mail_operation_is_mine (ModestMailOperation *self,
 {
        ModestMailOperationPrivate *priv;
 
+       g_return_val_if_fail (self && MODEST_IS_MAIL_OPERATION(self),
+                             FALSE);
+       
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
        if (priv->source == NULL) return FALSE;
 
@@ -425,7 +433,8 @@ modest_mail_operation_get_source (ModestMailOperation *self)
 {
        ModestMailOperationPrivate *priv;
 
-       g_return_val_if_fail (self, NULL);
+       g_return_val_if_fail (self && MODEST_IS_MAIL_OPERATION(self),
+                             NULL);
        
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
        if (!priv) {
@@ -477,8 +486,8 @@ modest_mail_operation_cancel (ModestMailOperation *self)
 {
        ModestMailOperationPrivate *priv;
        gboolean canceled = FALSE;
-
-       g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), FALSE);
+       
+       g_return_val_if_fail (self && MODEST_IS_MAIL_OPERATION (self), FALSE);
 
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
 
@@ -513,8 +522,9 @@ modest_mail_operation_get_task_done (ModestMailOperation *self)
 {
        ModestMailOperationPrivate *priv;
 
-       g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), 0);
-
+       g_return_val_if_fail (self && MODEST_IS_MAIL_OPERATION(self),
+                             0);
+       
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
        return priv->done;
 }
@@ -524,7 +534,8 @@ modest_mail_operation_get_task_total (ModestMailOperation *self)
 {
        ModestMailOperationPrivate *priv;
 
-       g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), 0);
+       g_return_val_if_fail (self && MODEST_IS_MAIL_OPERATION(self),
+                             0);
 
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
        return priv->total;
@@ -536,11 +547,9 @@ modest_mail_operation_is_finished (ModestMailOperation *self)
        ModestMailOperationPrivate *priv;
        gboolean retval = FALSE;
 
-       if (!MODEST_IS_MAIL_OPERATION (self)) {
-               g_warning ("%s: invalid parametter", G_GNUC_FUNCTION);
-               return retval;
-       }
-
+       g_return_val_if_fail (self && MODEST_IS_MAIL_OPERATION(self),
+                             FALSE);
+       
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
 
        if (priv->status == MODEST_MAIL_OPERATION_STATUS_SUCCESS   ||
@@ -603,9 +612,9 @@ modest_mail_operation_send_mail (ModestMailOperation *self,
        ModestMailOperationPrivate *priv;
        SendMsgInfo *info;
        
-       g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
-       g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
-       g_return_if_fail (TNY_IS_MSG (msg));
+       g_return_if_fail (self && MODEST_IS_MAIL_OPERATION (self));
+       g_return_if_fail (transport_account && TNY_IS_TRANSPORT_ACCOUNT (transport_account));
+       g_return_if_fail (msg && TNY_IS_MSG (msg));
        
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
 
@@ -648,47 +657,66 @@ static void
 common_send_mail_operation_end (TnySendQueue *queue, TnyMsg *msg,
                                SendMsgInfo *info)
 {
-       if (msg == info->msg) {
-               g_signal_handler_disconnect (queue, info->msg_sent_handler);
-               info->msg_sent_handler = 0;
-               g_signal_handler_disconnect (queue, info->error_happened_handler);
-               info->error_happened_handler = 0;
-               g_object_unref (info->msg);
-               modest_mail_operation_notify_end (info->mail_op);
-               g_object_unref (info->mail_op);
-               g_slice_free (SendMsgInfo, info);
-       }
+       g_signal_handler_disconnect (queue, info->msg_sent_handler);
+       g_signal_handler_disconnect (queue, info->error_happened_handler);
+
+       g_object_unref (info->msg);
+       modest_mail_operation_notify_end (info->mail_op);
+       g_object_unref (info->mail_op);
+
+       g_slice_free (SendMsgInfo, info);
 }
 
 static void     
 send_mail_msg_sent_handler (TnySendQueue *queue, TnyHeader *header, TnyMsg *msg,
                            guint nth, guint total, gpointer userdata)
 {
-       SendMsgInfo *info = (SendMsgInfo *) info;
-
-       if (msg == info->msg) {
+       SendMsgInfo *info = (SendMsgInfo *) userdata;
+       TnyHeader *hdr1, *hdr2;
+       const char *msgid1, *msgid2;
+       hdr1 = tny_msg_get_header(msg);
+       hdr2 = tny_msg_get_header(info->msg);
+       msgid1 = tny_header_get_message_id(hdr1);
+       msgid2 = tny_header_get_message_id(hdr2);
+       if (msgid1 == NULL) msgid1 = "(null)";
+       if (msgid2 == NULL) msgid2 = "(null)";
+
+       if (!strcmp (msgid1, msgid2)) {
                ModestMailOperationPrivate *priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op);
                priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
+
+               common_send_mail_operation_end (queue, msg, info);
        }
-               
-       common_send_mail_operation_end (queue, msg, info);
+       g_object_unref(G_OBJECT(hdr1));
+       g_object_unref(G_OBJECT(hdr2));
 }
 
 static void     
 send_mail_error_happened_handler (TnySendQueue *queue, TnyHeader *header, TnyMsg *msg,
                                  GError *error, gpointer userdata)
 {
-       SendMsgInfo *info = (SendMsgInfo *) info;
-
-       if (msg == info->msg) {
+       SendMsgInfo *info = (SendMsgInfo *) userdata;
+       TnyHeader *hdr1, *hdr2;
+       const char *msgid1, *msgid2;
+       
+       hdr1 = tny_msg_get_header(msg);
+       hdr2 = tny_msg_get_header(info->msg);
+       msgid1 = tny_header_get_message_id(hdr1);
+       msgid2 = tny_header_get_message_id(hdr2);
+       if (msgid1 == NULL) msgid1 = "(null)";
+       if (msgid2 == NULL) msgid2 = "(null)";
+
+       if (!strcmp (msgid1, msgid2)) {
                ModestMailOperationPrivate *priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op);
                priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
                g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
                             MODEST_MAIL_OPERATION_ERROR_OPERATION_CANCELED,
                             "modest: send mail failed\n");
+
+               common_send_mail_operation_end (queue, msg, info);
        }
-               
-       common_send_mail_operation_end (queue, msg, info);
+       g_object_unref(G_OBJECT(hdr1));
+       g_object_unref(G_OBJECT(hdr2));
 }
 
 
@@ -777,6 +805,7 @@ create_msg_thread (gpointer thread_data)
 
        g_object_unref (info->mail_op);
        g_slice_free (CreateMsgInfo, info);
+       if (new_msg) g_object_unref(new_msg);
        return NULL;
 }
 
@@ -908,7 +937,8 @@ modest_mail_operation_send_new_mail (ModestMailOperation *self,
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
        priv->op_type = MODEST_MAIL_OPERATION_TYPE_SEND;
        priv->account = TNY_ACCOUNT (g_object_ref (transport_account));
-
+       priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
+       
        /* Check parametters */
        if (to == NULL) {
                /* Set status failed and set an error */
@@ -1202,6 +1232,7 @@ typedef struct
        gboolean poke_all;
        TnyFolderObserver *inbox_observer;
        guint update_timeout;
+       RetrieveAllCallback retrieve_all_cb;
 } UpdateAccountInfo;
 
 
@@ -1248,9 +1279,9 @@ inbox_refreshed_cb (TnyFolder *inbox,
        GPtrArray *new_headers_array = NULL;   
        gint max_size, retrieve_limit, i;
        ModestAccountMgr *mgr;
-       gchar *retrieve_type = NULL;
+       ModestAccountRetrieveType retrieve_type;
        TnyList *new_headers = NULL;
-       gboolean headers_only;
+       gboolean headers_only, ignore_limit;
        TnyTransportAccount *transport_account;
        ModestTnySendQueue *send_queue;
 
@@ -1291,6 +1322,9 @@ inbox_refreshed_cb (TnyFolder *inbox,
        g_object_unref (info->inbox_observer);
        info->inbox_observer = NULL;
 
+       /* Update the last updated key, even if we don't have to get new headers */
+       modest_account_mgr_set_last_updated (mgr, tny_account_get_id (priv->account), time (NULL));
+       
        if (new_headers_array->len == 0)
                goto send_mail;
 
@@ -1301,17 +1335,23 @@ inbox_refreshed_cb (TnyFolder *inbox,
        
        /* Get per-account retrieval type */
        retrieve_type = modest_account_mgr_get_retrieve_type (mgr, info->account_name); 
-       headers_only = !g_ascii_strcasecmp (retrieve_type, MODEST_ACCOUNT_RETRIEVE_VALUE_HEADERS_ONLY);
-       g_free (retrieve_type);
+       headers_only = (retrieve_type == MODEST_ACCOUNT_RETRIEVE_HEADERS_ONLY);
 
        /* Order by date */
        g_ptr_array_sort (new_headers_array, (GCompareFunc) compare_headers_by_date);
        
-       /* TODO: Ask the user, instead of just failing,
-        * showing mail_nc_msg_count_limit_exceeded, with 'Get
-        * all' and 'Newest only' buttons. */
+       /* Ask the users if they want to retrieve all the messages
+          even though the limit was exceeded */
+       ignore_limit = FALSE;
        if (new_headers_array->len > retrieve_limit) {
-               /* TODO */
+               /* Ask the user if a callback has been specified and
+                  if the mail operation has a source (this means that
+                  was invoked by the user and not automatically by a
+                  D-Bus method) */
+               if (info->retrieve_all_cb && priv->source)
+                       ignore_limit = info->retrieve_all_cb (priv->source,
+                                                             new_headers_array->len,
+                                                             retrieve_limit);
        }
        
        if (!headers_only) {
@@ -1319,7 +1359,10 @@ inbox_refreshed_cb (TnyFolder *inbox,
                const gint msg_list_size = compute_message_array_size (new_headers_array);
 
                priv->done = 0;
-               priv->total = MIN (new_headers_array->len, retrieve_limit);
+               if (ignore_limit)
+                       priv->total = new_headers_array->len;
+               else
+                       priv->total = MIN (new_headers_array->len, retrieve_limit);
                while (msg_num < priv->total) {         
                        TnyHeader *header = TNY_HEADER (g_ptr_array_index (new_headers_array, msg_num));
                        TnyFolder *folder = tny_header_get_folder (header);
@@ -1350,9 +1393,6 @@ inbox_refreshed_cb (TnyFolder *inbox,
        g_ptr_array_foreach (new_headers_array, (GFunc) g_object_unref, NULL);
        g_ptr_array_free (new_headers_array, FALSE);
 
-       /* Update the last updated key */
-       modest_account_mgr_set_last_updated (mgr, tny_account_get_id (priv->account), time (NULL));
-
  send_mail:
        /* Send mails */
        priv->done = 0;
@@ -1509,6 +1549,7 @@ void
 modest_mail_operation_update_account (ModestMailOperation *self,
                                      const gchar *account_name,
                                      gboolean poke_all,
+                                     RetrieveAllCallback retrieve_all_cb,
                                      UpdateAccountCallback callback,
                                      gpointer user_data)
 {
@@ -1543,6 +1584,7 @@ modest_mail_operation_update_account (ModestMailOperation *self,
        info->callback = callback;
        info->user_data = user_data;
        info->update_timeout = g_timeout_add (250, timeout_notify_progress, self);
+       info->retrieve_all_cb = retrieve_all_cb;
 
        /* Set account busy */
        modest_account_mgr_set_account_busy (modest_runtime_get_account_mgr (), account_name, TRUE);
@@ -1550,9 +1592,9 @@ modest_mail_operation_update_account (ModestMailOperation *self,
 
        /* Get all folders and continue in the callback */    
        folders = tny_simple_list_new ();
-       tny_folder_store_get_folders_async (TNY_FOLDER_STORE (store_account),
-                                           folders, recurse_folders_async_cb, 
-                                           NULL, NULL, info);
+       tny_folder_store_get_folders_async (TNY_FOLDER_STORE (store_account),
+                               folders, recurse_folders_async_cb, 
+                               NULL, NULL, info);
 }
 
 /*
@@ -1593,341 +1635,67 @@ compare_headers_by_date (gconstpointer a,
                return -1;
 }
 
-/* static gpointer */
-/* update_account_thread (gpointer thr_user_data) */
-/* { */
-/*     static gboolean first_time = TRUE; */
-/*     UpdateAccountInfo *info = NULL; */
-/*     TnyList *all_folders = NULL, *new_headers = NULL; */
-/*     GPtrArray *new_headers_array = NULL; */
-/*     TnyIterator *iter = NULL; */
-/*     ModestMailOperationPrivate *priv = NULL; */
-/*     ModestTnySendQueue *send_queue = NULL; */
-/*     gint i = 0, timeout = 0; */
-
-/*     info = (UpdateAccountInfo *) thr_user_data; */
-/*     priv = MODEST_MAIL_OPERATION_GET_PRIVATE(info->mail_op); */
-
-/*     /\* Get account and set it into mail_operation *\/ */
-/*     priv->account = g_object_ref (info->account); */
-
-/*     /\* Get all the folders. We can do it synchronously because */
-/*        we're already running in a different thread than the UI *\/ */
-/*     all_folders = get_all_folders_from_account (info->account, &(priv->error)); */
-/*     if (!all_folders) { */
-/*             priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; */
-/*             goto out; */
-/*     } */
-
-/*     /\* Update status and notify. We need to call the notification */
-/*        with a source function in order to call it from the main */
-/*        loop. We need that in order not to get into trouble with */
-/*        Gtk+. We use a timeout in order to provide more status */
-/*        information, because the sync tinymail call does not */
-/*        provide it for the moment *\/ */
-/*     timeout = g_timeout_add (100, idle_notify_progress, info->mail_op); */
-
-/*     new_headers_array = g_ptr_array_new (); */
-/*     iter = tny_list_create_iterator (all_folders); */
-
-/*     while (!tny_iterator_is_done (iter) && !priv->error &&  */
-/*            priv->status != MODEST_MAIL_OPERATION_STATUS_CANCELED) { */
-
-/*             TnyFolderType folder_type; */
-/*             TnyFolder *folder = NULL; */
-
-/*             folder = TNY_FOLDER (tny_iterator_get_current (iter)); */
-/*             folder_type = tny_folder_get_folder_type (folder); */
-
-/*             /\* Refresh it only if it's the INBOX *\/ */
-/*             if (folder_type == TNY_FOLDER_TYPE_INBOX) { */
-/*                     InternalFolderObserver *observer = NULL; */
-/*                     TnyIterator *new_headers_iter = NULL; */
-
-/*                     /\* Refresh the folder. Our observer receives */
-/*                      * the new emails during folder refreshes, so */
-/*                      * we can use observer->new_headers */
-/*                      *\/ */
-/*                     observer = g_object_new (internal_folder_observer_get_type (), NULL); */
-/*                     tny_folder_add_observer (TNY_FOLDER (folder), TNY_FOLDER_OBSERVER (observer)); */
-               
-/*                     tny_folder_refresh (TNY_FOLDER (folder), &(priv->error)); */
 
-/*                     new_headers_iter = tny_list_create_iterator (observer->new_headers); */
-/*                     while (!tny_iterator_is_done (new_headers_iter)) { */
-/*                             TnyHeader *header = NULL; */
+/* ******************************************************************* */
+/* ************************** STORE  ACTIONS ************************* */
+/* ******************************************************************* */
 
-/*                             header = TNY_HEADER (tny_iterator_get_current (new_headers_iter)); */
-/*                             /\* Apply per-message size limits *\/ */
-/*                             if (tny_header_get_message_size (header) < info->max_size) */
-/*                                     g_ptr_array_add (new_headers_array, g_object_ref (header)); */
-                               
-/*                             g_object_unref (header); */
-/*                             tny_iterator_next (new_headers_iter); */
-/*                     } */
-/*                     g_object_unref (new_headers_iter); */
-
-/*                     tny_folder_remove_observer (TNY_FOLDER (folder), TNY_FOLDER_OBSERVER (observer)); */
-/*                     g_object_unref (observer); */
-/*             } else { */
-/*                     /\* We no not need to do it the first time, */
-/*                        because it's automatically done by the tree */
-/*                        model *\/ */
-/*                     if (G_LIKELY (!first_time)) */
-/*                             tny_folder_poke_status (folder); */
-/*             } */
-/*             g_object_unref (folder); */
-
-/*             tny_iterator_next (iter); */
-/*     } */
-/*     g_object_unref (G_OBJECT (iter)); */
-/*     g_source_remove (timeout); */
-
-/*     if (priv->status != MODEST_MAIL_OPERATION_STATUS_CANCELED &&  */
-/*         priv->status != MODEST_MAIL_OPERATION_STATUS_FAILED && */
-/*         new_headers_array->len > 0) { */
-/*             gint msg_num = 0; */
-
-/*             /\* Order by date *\/ */
-/*             g_ptr_array_sort (new_headers_array, (GCompareFunc) compare_headers_by_date); */
-
-/*             /\* TODO: Ask the user, instead of just failing, */
-/*              * showing mail_nc_msg_count_limit_exceeded, with 'Get */
-/*              * all' and 'Newest only' buttons. *\/ */
-/*             if (new_headers_array->len > info->retrieve_limit) { */
-/*                     /\* TODO *\/ */
-/*             } */
-
-/*             /\* Should be get only the headers or the message as well? *\/ */
-/*             if (g_ascii_strcasecmp (info->retrieve_type,  */
-/*                                     MODEST_ACCOUNT_RETRIEVE_VALUE_HEADERS_ONLY) != 0) {      */
-/*                     priv->done = 0; */
-/*                     priv->total = MIN (new_headers_array->len, info->retrieve_limit); */
-/*                     while (msg_num < priv->total) { */
-
-/*                             TnyHeader *header = TNY_HEADER (g_ptr_array_index (new_headers_array, msg_num)); */
-/*                             TnyFolder *folder = tny_header_get_folder (header); */
-/*                             TnyMsg *msg       = tny_folder_get_msg (folder, header, NULL); */
-/*                             ModestMailOperationState *state; */
-/*                             ModestPair* pair; */
-
-/*                             priv->done++; */
-/*                             /\* We can not just use the mail operation because the */
-/*                                values of done and total could change before the */
-/*                                idle is called *\/ */
-/*                             state = modest_mail_operation_clone_state (info->mail_op); */
-/*                             pair = modest_pair_new (g_object_ref (info->mail_op), state, FALSE); */
-/*                             g_idle_add_full (G_PRIORITY_HIGH_IDLE, idle_notify_progress_once, */
-/*                                              pair, (GDestroyNotify) modest_pair_free); */
-
-/*                             g_object_unref (msg); */
-/*                             g_object_unref (folder); */
-
-/*                             msg_num++; */
-/*                     } */
-/*             } */
-/*     } */
-
-/*     if (priv->status == MODEST_MAIL_OPERATION_STATUS_CANCELED) */
-/*             goto out; */
-
-/*     /\* Copy the headers to a list and free the array *\/ */
-/*     new_headers = tny_simple_list_new (); */
-/*     for (i=0; i < new_headers_array->len; i++) { */
-/*             TnyHeader *header = TNY_HEADER (g_ptr_array_index (new_headers_array, i)); */
-/*             tny_list_append (new_headers, G_OBJECT (header)); */
-/*     } */
-/*     g_ptr_array_foreach (new_headers_array, (GFunc) g_object_unref, NULL); */
-/*     g_ptr_array_free (new_headers_array, FALSE); */
-       
+typedef struct {
+       ModestMailOperation *mail_op;
+       CreateFolderUserCallback callback;
+       gpointer user_data;
+} CreateFolderInfo;
 
-/*     /\* Perform send (if operation was not cancelled) *\/ */
-/*     priv->done = 0; */
-/*     priv->total = 0; */
-/*     if (priv->account != NULL)  */
-/*             g_object_unref (priv->account); */
 
-/*     if (info->transport_account) { */
-/*             priv->account = g_object_ref (info->transport_account); */
-       
-/*             send_queue = modest_runtime_get_send_queue (info->transport_account); */
-/*             if (send_queue) { */
-/*                     modest_tny_send_queue_try_to_send (send_queue); */
-/*             } else { */
-/*                     g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, */
-/*                                  MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED, */
-/*                                  "cannot create a send queue for %s\n",  */
-/*                                  tny_account_get_name (TNY_ACCOUNT (info->transport_account))); */
-/*                     priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; */
-/*             } */
-/*     } */
-       
-/*     /\* Check if the operation was a success *\/ */
-/*     if (!priv->error) { */
-/*             priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS; */
-
-/*             /\* Update the last updated key *\/ */
-/*             g_idle_add_full (G_PRIORITY_HIGH_IDLE,  */
-/*                              set_last_updated_idle,  */
-/*                              g_strdup (tny_account_get_id (TNY_ACCOUNT (info->account))), */
-/*                              (GDestroyNotify) g_free); */
-/*     } */
-
-/*  out: */
-/*     /\* Set the account back to not busy *\/ */
-/*     modest_account_mgr_set_account_busy (modest_runtime_get_account_mgr(),  */
-/*                                          info->account_name, FALSE); */
-       
-/*     if (info->callback) { */
-/*             UpdateAccountInfo *idle_info; */
-
-/*             /\* This thread is not in the main lock *\/ */
-/*             idle_info = g_malloc0 (sizeof (UpdateAccountInfo)); */
-/*             idle_info->mail_op = g_object_ref (info->mail_op); */
-/*             idle_info->new_headers = (new_headers) ? g_object_ref (new_headers) : NULL; */
-/*             idle_info->callback = info->callback; */
-/*             idle_info->user_data = info->user_data; */
-/*             g_idle_add (idle_update_account_cb, idle_info); */
-/*     } */
-
-/*     /\* Notify about operation end. Note that the info could be */
-/*        freed before this idle happens, but the mail operation will */
-/*        be still alive *\/ */
-/*     g_idle_add (idle_notify_queue, g_object_ref (info->mail_op)); */
-
-/*     /\* Frees *\/ */
-/*     if (new_headers) */
-/*             g_object_unref (new_headers); */
-/*     if (all_folders) */
-/*             g_object_unref (all_folders); */
-/*     g_object_unref (info->account); */
-/*     if (info->transport_account) */
-/*             g_object_unref (info->transport_account); */
-/*     g_free (info->account_name); */
-/*     g_free (info->retrieve_type); */
-/*     g_slice_free (UpdateAccountInfo, info); */
-
-/*     first_time = FALSE; */
-
-/*     return NULL; */
-/* } */
-
-/* gboolean */
-/* modest_mail_operation_update_account (ModestMailOperation *self, */
-/*                                   const gchar *account_name, */
-/*                                   UpdateAccountCallback callback, */
-/*                                   gpointer user_data) */
-/* { */
-/*     GThread *thread = NULL; */
-/*     UpdateAccountInfo *info = NULL; */
-/*     ModestMailOperationPrivate *priv = NULL; */
-/*     ModestAccountMgr *mgr = NULL; */
-/*     TnyStoreAccount *store_account = NULL; */
-/*     TnyTransportAccount *transport_account = NULL; */
-
-/*     g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), FALSE); */
-/*     g_return_val_if_fail (account_name, FALSE); */
-
-/*     /\* Init mail operation. Set total and done to 0, and do not */
-/*        update them, this way the progress objects will know that */
-/*        we have no clue about the number of the objects *\/ */
-/*     priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self); */
-/*     priv->total = 0; */
-/*     priv->done  = 0; */
-/*     priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS; */
-/*     priv->op_type = MODEST_MAIL_OPERATION_TYPE_RECEIVE; */
-
-/*     /\* Get the store account *\/ */
-/*     store_account = (TnyStoreAccount *) */
-/*             modest_tny_account_store_get_server_account (modest_runtime_get_account_store (), */
-/*                                                                  account_name, */
-/*                                                                  TNY_ACCOUNT_TYPE_STORE); */
-                                                                    
-/*     if (!store_account) { */
-/*             g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, */
-/*                          MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND, */
-/*                          "cannot get tny store account for %s\n", account_name); */
-/*             goto error; */
-/*     } */
-
-/*     priv->account = g_object_ref (store_account); */
-       
-/*     /\* Get the transport account, we can not do it in the thread */
-/*        due to some problems with dbus *\/ */
-/*     transport_account = (TnyTransportAccount *) */
-/*             modest_tny_account_store_get_transport_account_for_open_connection (modest_runtime_get_account_store(), */
-/*                                                                                 account_name); */
-/*     if (!transport_account) { */
-/*             g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, */
-/*                          MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND, */
-/*                          "cannot get tny transport account for %s\n", account_name); */
-/*             goto error; */
-/*     } */
-
-/*     /\* Create the helper object *\/ */
-/*     info = g_slice_new (UpdateAccountInfo); */
-/*     info->mail_op = self; */
-/*     info->account = store_account; */
-/*     info->transport_account = transport_account; */
-/*     info->callback = callback; */
-/*     info->account_name = g_strdup (account_name); */
-/*     info->user_data = user_data; */
-
-/*     /\* Get the message size limit *\/ */
-/*     info->max_size  = modest_conf_get_int (modest_runtime_get_conf (),  */
-/*                                            MODEST_CONF_MSG_SIZE_LIMIT, NULL); */
-/*     if (info->max_size == 0) */
-/*             info->max_size = G_MAXINT; */
-/*     else */
-/*             info->max_size = info->max_size * KB; */
-
-/*     /\* Get per-account retrieval type *\/ */
-/*     mgr = modest_runtime_get_account_mgr (); */
-/*     info->retrieve_type = modest_account_mgr_get_retrieve_type (mgr, account_name); */
-
-/*     /\* Get per-account message amount retrieval limit *\/ */
-/*     info->retrieve_limit = modest_account_mgr_get_retrieve_limit (mgr, account_name); */
-/*     if (info->retrieve_limit == 0) */
-/*             info->retrieve_limit = G_MAXINT; */
-               
-/*     /\* printf ("DEBUG: %s: info->retrieve_limit = %d\n", __FUNCTION__, info->retrieve_limit); *\/ */
+static void
+create_folder_cb (TnyFolderStore *parent_folder, 
+                 gboolean canceled, 
+                 TnyFolder *new_folder, 
+                 GError *err, 
+                 gpointer user_data)
+{
+       ModestMailOperationPrivate *priv;
+       CreateFolderInfo *info;
 
-/*     /\* Set account busy *\/ */
-/*     modest_account_mgr_set_account_busy(mgr, account_name, TRUE); */
-       
-/*     modest_mail_operation_notify_start (self); */
-/*     thread = g_thread_create (update_account_thread, info, FALSE, NULL); */
-
-/*     return TRUE; */
-
-/*  error: */
-/*     if (store_account) */
-/*             g_object_unref (store_account); */
-/*     if (transport_account) */
-/*             g_object_unref (transport_account); */
-/*     priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; */
-/*     if (callback) { */
-/*             callback (self, NULL, user_data); */
-/*     } */
-/*     modest_mail_operation_notify_end (self); */
-/*     return FALSE; */
-/* } */
+       info = (CreateFolderInfo *) user_data;
+       priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op);
 
-/* ******************************************************************* */
-/* ************************** STORE  ACTIONS ************************* */
-/* ******************************************************************* */
+       if (canceled || err) {
+               priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
+               if (err)
+                       priv->error = g_error_copy (err);
+               else
+                       g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
+                                    MODEST_MAIL_OPERATION_ERROR_OPERATION_CANCELED,
+                                    "canceled");               
+       } else {
+               priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
+       }
 
+       /* The user will unref the new_folder */
+       if (info->callback)
+               info->callback (info->mail_op, parent_folder, 
+                               new_folder, info->user_data);
+       
+       /* Notify about operation end */
+       modest_mail_operation_notify_end (info->mail_op);
+
+       /* Frees */
+       g_object_unref (info->mail_op);
+       g_slice_free (CreateFolderInfo, info);
+}
 
-TnyFolder *
+void
 modest_mail_operation_create_folder (ModestMailOperation *self,
                                     TnyFolderStore *parent,
-                                    const gchar *name)
+                                    const gchar *name,
+                                    CreateFolderUserCallback callback,
+                                    gpointer user_data)
 {
        ModestMailOperationPrivate *priv;
-       TnyFolder *new_folder = NULL;
 
-       g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent), NULL);
-       g_return_val_if_fail (name, NULL);
+       g_return_if_fail (TNY_IS_FOLDER_STORE (parent));
+       g_return_if_fail (name);
        
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
        priv->op_type = MODEST_MAIL_OPERATION_TYPE_INFO;
@@ -1964,18 +1732,25 @@ modest_mail_operation_create_folder (ModestMailOperation *self,
        }
 
        if (!priv->error) {
-               /* Create the folder */
-               modest_mail_operation_notify_start (self);
-               new_folder = tny_folder_store_create_folder (parent, name, &(priv->error));
-               CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED);
-               if (!priv->error)
-                       priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
-       }
+               CreateFolderInfo *info;
 
-       /* Notify about operation end */
-       modest_mail_operation_notify_end (self);
+               info = g_slice_new0 (CreateFolderInfo);
+               info->mail_op = g_object_ref (self);
+               info->callback = callback;
+               info->user_data = user_data;
+
+               modest_mail_operation_notify_start (self);
 
-       return new_folder;
+               /* Create the folder */
+               tny_folder_store_create_folder_async (parent, name, create_folder_cb, 
+                                                     NULL, info);
+       } else {
+               /* Call the user callback anyway */
+               if (callback)
+                       callback (self, parent, NULL, user_data);
+               /* Notify about operation end */
+               modest_mail_operation_notify_end (self);
+       }
 }
 
 void
@@ -2591,16 +2366,32 @@ modest_mail_operation_remove_msg (ModestMailOperation *self,
        /* remove message from folder */
        tny_folder_remove_msg (folder, header, &(priv->error));
        if (!priv->error) {
+               gboolean expunge, leave_on_server;
+               const gchar *account_name;
+               TnyAccount *account;
+
                tny_header_set_flag (header, TNY_HEADER_FLAG_DELETED);
                tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
 
                modest_mail_operation_notify_start (self);
 
-               if (TNY_IS_CAMEL_IMAP_FOLDER (folder) ||
-                   TNY_IS_CAMEL_POP_FOLDER (folder))
-                       tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /* FALSE --> dont expunge */
+               /* Get leave on server setting */
+               account = tny_folder_get_account (folder);
+               account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
+               leave_on_server =
+                       modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
+                                                               account_name);
+
+               if (TNY_IS_CAMEL_POP_FOLDER (folder) && !leave_on_server)
+                       expunge = TRUE;
                else
-                       tny_folder_sync_async(folder, TRUE, NULL, NULL, NULL); /* TRUE --> expunge */
+                       expunge = FALSE;
+
+               /* Sync folder */
+               tny_folder_sync_async(folder, expunge, NULL, NULL, NULL);
+
+               /* Unref */
+               g_object_unref (account);
        }
        
        
@@ -2685,12 +2476,25 @@ modest_mail_operation_remove_msgs (ModestMailOperation *self,
 
        tny_folder_remove_msgs (folder, remove_headers, &(priv->error));
        if (!priv->error) {
-               if (TNY_IS_CAMEL_IMAP_FOLDER (folder) || 
-                   TNY_IS_CAMEL_POP_FOLDER (folder))
-                       tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /* FALSE --> don't expunge */ 
+               gboolean expunge, leave_on_server;
+               const gchar *account_name;
+               TnyAccount *account;
+               
+               account = tny_folder_get_account (folder);
+               account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
+               leave_on_server =
+                       modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
+                                       account_name);
+
+               if (TNY_IS_CAMEL_POP_FOLDER (folder) && !leave_on_server)
+                       expunge = TRUE;
                else
-                       /* local folders */
-                       tny_folder_sync_async(folder, TRUE, NULL, NULL, NULL); /* TRUE --> expunge */
+                       expunge = FALSE;
+
+               /* Sync folder */
+               tny_folder_sync_async(folder, expunge, NULL, NULL, NULL);
+               
+               g_object_unref (account);
        }