Merge patch to merge-back sessionwork to trunk



FYI and attached. This merge-work will most likely be committed tomorrow
noon (noon in Europe).

-- 
Philip Van Hoof, software developer
home: me at pvanhoof dot be 
gnome: pvanhoof at gnome dot org 
http://www.pvanhoof.be/blog



Index: libtinymail-gpe/tny-gpe-account-store.c
===================================================================
--- libtinymail-gpe/tny-gpe-account-store.c	(revision 2535)
+++ libtinymail-gpe/tny-gpe-account-store.c	(working copy)
@@ -153,11 +153,7 @@
 	gchar *ptr = strrchr (key, '/'); ptr++;
 
 	if (!strcmp (ptr, "count"))
-	{
 		kill_stored_accounts (priv);
-		g_signal_emit (self, 
-			tny_account_store_signals [TNY_ACCOUNT_STORE_ACCOUNTS_RELOADED], 0);
-	}
 
 	g_free (key);
 
@@ -493,35 +489,6 @@
 }
 
 
-
-void
-tny_gpe_account_store_add_store_account (TnyGpeAccountStore *self, TnyStoreAccount *account)
-{
-	TnyGpeAccountStorePriv *priv = TNY_GPE_ACCOUNT_STORE_GET_PRIVATE (self);
-
-	tny_gpe_account_store_notify_remove (TNY_ACCOUNT_STORE (self));
-	tny_gpe_account_store_add_account (TNY_ACCOUNT_STORE (self), TNY_ACCOUNT (account), "store");
-	tny_gpe_account_store_notify_add (TNY_ACCOUNT_STORE (self));
-
-	g_signal_emit (self, tny_account_store_signals [TNY_ACCOUNT_STORE_ACCOUNT_INSERTED], 0, account);
-
-	return;
-}
-
-void
-tny_gpe_account_store_add_transport_account (TnyGpeAccountStore *self, TnyTransportAccount *account)
-{
-	TnyGpeAccountStorePriv *priv = TNY_GPE_ACCOUNT_STORE_GET_PRIVATE (self);
-
-	tny_gpe_account_store_notify_remove (TNY_ACCOUNT_STORE (self));
-	tny_gpe_account_store_add_account (TNY_ACCOUNT_STORE (self), TNY_ACCOUNT (account), "transport");
-	tny_gpe_account_store_notify_add (TNY_ACCOUNT_STORE (self));
-
-	g_signal_emit (self, tny_account_store_signals [TNY_ACCOUNT_STORE_ACCOUNT_INSERTED], 0, account);
-
-	return;
-}
-
 static TnyDevice*
 tny_gpe_account_store_get_device (TnyAccountStore *self)
 {
Index: libtinymail-gpe/tny-gpe-account-store.h
===================================================================
--- libtinymail-gpe/tny-gpe-account-store.h	(revision 2535)
+++ libtinymail-gpe/tny-gpe-account-store.h	(working copy)
@@ -52,9 +52,6 @@
 TnyAccountStore* tny_gpe_account_store_new (void);
 TnySessionCamel* tny_gpe_account_store_get_session (TnyGpeAccountStore *self);
 
-void tny_gpe_account_store_add_transport_account (TnyGpeAccountStore *self, TnyTransportAccount *account);
-void tny_gpe_account_store_add_store_account (TnyGpeAccountStore *self, TnyStoreAccount *account);
-
 G_END_DECLS
 
 #endif
Index: libtinymail-camel/tny-camel-folder.c
===================================================================
--- libtinymail-camel/tny-camel-folder.c	(revision 2535)
+++ libtinymail-camel/tny-camel-folder.c	(working copy)
@@ -514,10 +514,17 @@
 	CamelException ex = CAMEL_EXCEPTION_INITIALISER;
 	gboolean haderr = FALSE;
 
-	g_assert (TNY_IS_CAMEL_MSG (msg));
+	if (!TNY_IS_CAMEL_MSG (msg))
+	{
+		g_critical ("You must not use a non-TnyCamelMsg implementation "
+			"of TnyMsg with TnyCamelFolder types. This indicates a "
+			"problem in the software (unsupported operation)\n");
+		g_assert (TNY_IS_CAMEL_MSG (msg));
+	}
 
-	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, err, 
-			TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_ADD_MSG))
+	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), 
+			priv->account, err, TNY_FOLDER_ERROR, 
+			TNY_FOLDER_ERROR_ADD_MSG))
 		return;
 
 	g_static_rec_mutex_lock (priv->folder_lock);
@@ -538,16 +545,20 @@
 		GPtrArray *dst_orig_uids = NULL;
 		gint a = 0, len = 0, nlen = 0;
 		CamelException ex2 = CAMEL_EXCEPTION_INITIALISER;
+
 		len = priv->folder->summary->messages->len;
 		dst_orig_uids = g_ptr_array_sized_new (len);
-		for (a = 0; a < len; a++) {
-			CamelMessageInfo *om = camel_folder_summary_index (priv->folder->summary, a);
+
+		for (a = 0; a < len; a++) 
+		{
+			CamelMessageInfo *om = 
+				camel_folder_summary_index (priv->folder->summary, a);
 			if (om && om->uid)
 				g_ptr_array_add (dst_orig_uids, g_strdup (om->uid));
 			if (om)
 				camel_message_info_free (om);
 		}
-	
+
 		camel_folder_append_message (priv->folder, message, NULL, NULL, &ex);
 		priv->unread_length = camel_folder_get_unread_message_count (priv->folder);
 		priv->cached_length = camel_folder_get_message_count (priv->folder);
@@ -557,8 +568,11 @@
 
 		for (a = 0; a < nlen; a++) 
 		{
-			CamelMessageInfo *om = camel_folder_summary_index (priv->folder->summary, a);
-			if (om && om->uid) {
+			CamelMessageInfo *om = 
+				camel_folder_summary_index (priv->folder->summary, a);
+
+			if (om && om->uid) 
+			{
 				gint b = 0;
 				gboolean found = FALSE;
 
@@ -648,8 +662,9 @@
 
 	g_assert (TNY_IS_HEADER (header));
 
-	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, err, 
-			TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_REMOVE_MSG))
+	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), 
+			priv->account, err, TNY_FOLDER_ERROR, 
+			TNY_FOLDER_ERROR_REMOVE_MSG))
 		return;
 
 	if (!priv->remove_strat) {
@@ -669,7 +684,6 @@
 
 	tny_msg_remove_strategy_perform_remove (priv->remove_strat, self, header, err);
 
-
 	/* Notify about unread count */
 	_tny_camel_folder_check_unread_count (TNY_CAMEL_FOLDER (self));
 
@@ -795,7 +809,6 @@
 {
 	TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
 	priv->cached_length = len;
-
 	return;
 }
 
@@ -805,7 +818,6 @@
 {
 	TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
 	priv->local_size = len;
-
 	return;
 }
 
@@ -819,7 +831,6 @@
 tny_camel_folder_get_all_count_default (TnyFolder *self)
 {
 	TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
-
 	return priv->cached_length;
 }
 
@@ -834,7 +845,6 @@
 tny_camel_folder_get_account_default (TnyFolder *self)
 {
 	TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
-
 	return TNY_ACCOUNT (g_object_ref (priv->account));
 }
 
@@ -851,12 +861,11 @@
 	return;
 }
 
-/**
- * When using a #GMainLoop this method will execute a callback using
+/* When using a #GMainLoop this method will execute a callback using
  * g_idle_add_full.  Note that without a #GMainLoop, the callbacks
  * could happen in a worker thread (depends on who call it) at an
- * unknown moment in time (check your locking in this case).
- */
+ * unknown moment in time (check your locking in this case). */
+
 static void
 execute_callback (gint depth, 
 		  gint priority,
@@ -887,8 +896,9 @@
 	TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
 	CamelException ex = CAMEL_EXCEPTION_INITIALISER;
 
-	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, err, 
-			TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_SYNC))
+	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), 
+			priv->account, err, TNY_FOLDER_ERROR, 
+			TNY_FOLDER_ERROR_SYNC))
 		return;
 
 	g_static_rec_mutex_lock (priv->folder_lock);
@@ -948,10 +958,10 @@
 	TnyFolder *self = info->self;
 	TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
 
-	_tny_camel_folder_unreason (priv);
-
 	/* thread reference */
+	_tny_camel_folder_unreason (priv);
 	g_object_unref (G_OBJECT (self));
+
 	if (info->err)
 		g_error_free (info->err);
 
@@ -960,10 +970,12 @@
 	tny_idle_stopper_destroy (info->stopper);
 	info->stopper = NULL;
 
-	g_mutex_lock (info->mutex);
-	g_cond_broadcast (info->condition);
-	info->had_callback = TRUE;
-	g_mutex_unlock (info->mutex);
+	if (info->condition) {
+		g_mutex_lock (info->mutex);
+		g_cond_broadcast (info->condition);
+		info->had_callback = TRUE;
+		g_mutex_unlock (info->mutex);
+	}
 
 	return;
 }
@@ -976,16 +988,16 @@
 	TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
 	TnyFolderChange *change = tny_folder_change_new (self);
 
-	if (info->callback)
-		info->callback (info->self, info->cancelled, &info->err, info->user_data);
-
-	tny_idle_stopper_stop (info->stopper);
-
 	tny_folder_change_set_new_all_count (change, priv->cached_length);
 	tny_folder_change_set_new_unread_count (change, priv->unread_length);
 	notify_folder_observers_about (self, change);
 	g_object_unref (change);
 
+	if (info->callback)
+		info->callback (info->self, info->cancelled, &info->err, info->user_data);
+
+	tny_idle_stopper_stop (info->stopper);
+
 	return FALSE;
 }
 
@@ -1023,6 +1035,7 @@
 	if (!load_folder_no_lock (priv))
 	{
 		tny_camel_folder_sync_async_destroyer (info);
+		g_slice_free (SyncFolderInfo, thr_user_data);
 		g_static_rec_mutex_unlock (priv->folder_lock);
 		return NULL;
 	}
@@ -1067,6 +1080,7 @@
 			  tny_camel_folder_sync_async_callback, info, 
 			  tny_camel_folder_sync_async_destroyer);
 
+
 	/* Wait on the queue for the mainloop callback to be finished */
 	g_mutex_lock (info->mutex);
 	if (!info->had_callback)
@@ -1085,22 +1099,21 @@
 tny_camel_folder_sync_async_cancelled_destroyer (gpointer thr_user_data)
 {
 	SyncFolderInfo *info = thr_user_data;
-
 	g_error_free (info->err);
 	g_object_unref (info->self);
 	g_slice_free (SyncFolderInfo, thr_user_data);
+	return;
 }
 
 static gboolean
 tny_camel_folder_sync_async_cancelled_callback (gpointer thr_user_data)
 {
 	SyncFolderInfo *info = thr_user_data;
-
 	if (info->callback)
 		info->callback (info->self, TRUE, &info->err, info->user_data);
-
 	return FALSE;
 }
+
 void 
 tny_camel_folder_sync_async_default (TnyFolder *self, gboolean expunge, TnySyncFolderCallback callback, TnyStatusCallback status_callback, gpointer user_data)
 {
@@ -1118,6 +1131,7 @@
 	info->user_data = user_data;
 	info->depth = g_main_depth ();
 	info->expunge = expunge;
+	info->condition = NULL;
 
 	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, &err, 
 					   TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_SYNC))
@@ -1125,7 +1139,6 @@
 		if (callback) {
 			info->err = g_error_copy (err);
 			g_object_ref (info->self);
-
 			execute_callback (info->depth, G_PRIORITY_DEFAULT,
 					  tny_camel_folder_sync_async_cancelled_callback, info, 
 					  tny_camel_folder_sync_async_cancelled_destroyer);
@@ -1137,7 +1150,7 @@
 	info->stopper = tny_idle_stopper_new();
 
 	/* thread reference */
-	g_object_ref (G_OBJECT (self));
+	g_object_ref (info->self);
 	_tny_camel_folder_reason (priv);
 
 	_tny_camel_queue_launch (TNY_FOLDER_PRIV_GET_QUEUE (priv), 
@@ -1158,8 +1171,6 @@
 	TnyStatusCallback status_callback;
 	gpointer user_data;
 	gboolean cancelled;
-	/* This stops us from calling a status callback after the operation has 
-	 * finished. */
 	TnyIdleStopper* stopper;
 	guint depth;
 	GError *err;
@@ -1173,8 +1184,8 @@
 
 
 /** This is the GDestroyNotify callback provided to g_idle_add_full()
- * for tny_camel_folder_refresh_async_callback().
- */
+ * for tny_camel_folder_refresh_async_callback().*/
+
 static void
 tny_camel_folder_refresh_async_destroyer (gpointer thr_user_data)
 {
@@ -1182,10 +1193,10 @@
 	TnyFolder *self = info->self;
 	TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
 
-	_tny_camel_folder_unreason (priv);
-
 	/* thread reference */
+	_tny_camel_folder_unreason (priv);
 	g_object_unref (G_OBJECT (self));
+
 	if (info->err)
 		g_error_free (info->err);
 
@@ -1194,10 +1205,12 @@
 	tny_idle_stopper_destroy (info->stopper);
 	info->stopper = NULL;
 
-	g_mutex_lock (info->mutex);
-	g_cond_broadcast (info->condition);
-	info->had_callback = TRUE;
-	g_mutex_unlock (info->mutex);
+	if (info->condition) {
+		g_mutex_lock (info->mutex);
+		g_cond_broadcast (info->condition);
+		info->had_callback = TRUE;
+		g_mutex_unlock (info->mutex);
+	}
 
 	return;
 }
@@ -1210,19 +1223,20 @@
 	TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
 	TnyFolderChange *change = tny_folder_change_new (self);
 
+	tny_folder_change_set_new_all_count (change, priv->cached_length);
+	tny_folder_change_set_new_unread_count (change, priv->unread_length);
+	notify_folder_observers_about (self, change);
+	g_object_unref (change);
+
 	if (info->callback)
 		info->callback (info->self, info->cancelled, &info->err, info->user_data);
 
 	/* Prevent status callbacks from being called after this
 	 * (can happen because the 2 idle callbacks have different priorities)
 	 * by causing tny_idle_stopper_is_stopped() to return TRUE. */
+
 	tny_idle_stopper_stop (info->stopper);
 
-	tny_folder_change_set_new_all_count (change, priv->cached_length);
-	tny_folder_change_set_new_unread_count (change, priv->unread_length);
-	notify_folder_observers_about (self, change);
-	g_object_unref (change);
-
 	return FALSE;
 }
 
@@ -1260,6 +1274,7 @@
 	if (!load_folder_no_lock (priv))
 	{
 		tny_camel_folder_refresh_async_destroyer (info);
+		g_slice_free (RefreshFolderInfo, info);
 		g_static_rec_mutex_unlock (priv->folder_lock);
 		return NULL;
 	}
@@ -1299,15 +1314,9 @@
 	info->condition = g_cond_new ();
 	info->had_callback = FALSE;
 
-	if (info->callback)
-	{
-		execute_callback (info->depth, G_PRIORITY_DEFAULT, 
-				  tny_camel_folder_refresh_async_callback, info, 
-				  tny_camel_folder_refresh_async_destroyer);
-	} else { /* Thread reference */
-		g_object_unref (G_OBJECT (self));
-		_tny_camel_folder_unreason (priv);
-	}
+	execute_callback (info->depth, G_PRIORITY_DEFAULT, 
+			  tny_camel_folder_refresh_async_callback, info, 
+			  tny_camel_folder_refresh_async_destroyer);
 
 	/* Wait on the queue for the mainloop callback to be finished */
 	g_mutex_lock (info->mutex);
@@ -1333,20 +1342,18 @@
 tny_camel_folder_refresh_async_cancelled_destroyer (gpointer thr_user_data)
 {
 	RefreshFolderInfo *info = thr_user_data;
-
 	g_error_free (info->err);
 	g_object_unref (info->self);
 	g_slice_free (RefreshFolderInfo, thr_user_data);
+	return;
 }
 
 static gboolean
 tny_camel_folder_refresh_async_cancelled_callback (gpointer thr_user_data)
 {
 	RefreshFolderInfo *info = thr_user_data;
-
 	if (info->callback)
 		info->callback (info->self, TRUE, &info->err, info->user_data);
-
 	return FALSE;
 }
 
@@ -1364,6 +1371,7 @@
  * Important is to add and remove references. You don't want the reference to
  * become zero while doing stuff on the instance in the background, don't you?
  **/
+
 static void
 tny_camel_folder_refresh_async_default (TnyFolder *self, TnyRefreshFolderCallback callback, TnyStatusCallback status_callback, gpointer user_data)
 {
@@ -1380,6 +1388,7 @@
 	info->status_callback = status_callback;
 	info->user_data = user_data;
 	info->depth = g_main_depth ();
+	info->condition = NULL;
 
 	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, &err, 
 					   TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_REFRESH))
@@ -1387,7 +1396,6 @@
 		if (callback) {
 			info->err = g_error_copy (err);
 			g_object_ref (info->self);
-
 			execute_callback (info->depth, G_PRIORITY_DEFAULT,
 					  tny_camel_folder_refresh_async_cancelled_callback, info, 
 					  tny_camel_folder_refresh_async_cancelled_destroyer);
@@ -1431,8 +1439,9 @@
 	guint oldlen, oldurlen;
 	TnyFolderChange *change = NULL;
 
-	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, err, 
-			TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_REFRESH))
+	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), 
+			priv->account, err, TNY_FOLDER_ERROR, 
+			TNY_FOLDER_ERROR_REFRESH))
 		return;
 
 	g_static_rec_mutex_lock (priv->folder_lock);
@@ -1444,9 +1453,6 @@
 		return;
 	}
 
-	/*_tny_camel_account_start_camel_operation (TNY_CAMEL_ACCOUNT (priv->account), 
-		NULL, NULL, NULL); */
-
 	oldlen = priv->cached_length;
 	oldurlen = priv->unread_length;
 
@@ -1454,14 +1460,11 @@
 	camel_folder_refresh_info (priv->folder, &ex);
 	priv->want_changes = TRUE;
 
-	/* _tny_camel_account_stop_camel_operation (TNY_CAMEL_ACCOUNT (priv->account)); */
-
 	priv->cached_length = camel_folder_get_message_count (priv->folder);    
 	if (G_LIKELY (priv->folder) && CAMEL_IS_FOLDER (priv->folder) && G_LIKELY (priv->has_summary_cap)) 
 		priv->unread_length = (guint) camel_folder_get_unread_message_count (priv->folder);
 	update_iter_counts (priv);
 
-
 	if (camel_exception_is_set (&ex))
 	{
 		g_set_error (err, TNY_FOLDER_ERROR, 
@@ -1506,14 +1509,11 @@
 	/* TODO: Proxy instantiation (happens a lot, could use a pool) */
 
 	header = _tny_camel_header_new ();
+	_tny_camel_header_set_folder ((TnyCamelHeader *) header, (TnyCamelFolder *) self, priv);
+	_tny_camel_header_set_camel_message_info ((TnyCamelHeader *) header, mi, FALSE);
+	tny_list_prepend (headers, (GObject*) header);
+	g_object_unref (header);
 
-	_tny_camel_header_set_folder (TNY_CAMEL_HEADER (header), TNY_CAMEL_FOLDER (self), priv);
-	_tny_camel_header_set_camel_message_info (TNY_CAMEL_HEADER (header), mi, FALSE);
-
-	tny_list_prepend (headers, (GObject*)header);
-
-	g_object_unref (G_OBJECT (header));
-
 	return;
 }
 
@@ -1537,9 +1537,6 @@
 			TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_REFRESH))
 		return;
 
-	/* we reason the folder to make sure it does not
-	 * lose all the references and uncache, causing an interlock */
-	_tny_camel_folder_reason (priv);
 	g_static_rec_mutex_lock (priv->folder_lock);
 
 	if (!load_folder_no_lock (priv))
@@ -1549,8 +1546,11 @@
 		return;
 	}
 
-	g_object_ref (G_OBJECT (headers));
+	/* We reason the folder to make sure it does not lose all the references
+	 * and uncache, causing an interlock */
+	_tny_camel_folder_reason (priv);
 
+	g_object_ref (headers);
 	ptr = g_slice_new (FldAndPriv);
 	ptr->self = self;
 	ptr->priv = priv;
@@ -1576,7 +1576,8 @@
 
 	g_slice_free (FldAndPriv, ptr);
 
-	g_object_unref (G_OBJECT (headers));
+	g_object_unref (headers);
+
 	g_static_rec_mutex_unlock (priv->folder_lock);
 	_tny_camel_folder_unreason (priv);
 
@@ -1612,18 +1613,8 @@
 tny_camel_folder_get_msg_async_destroyer (gpointer thr_user_data)
 {
 	GetMsgInfo *info = (GetMsgInfo *) thr_user_data;
-	TnyFolderChange *change;
 	TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (info->self);
 
-	if (info->msg) 
-	{
-		change = tny_folder_change_new (info->self);
-		tny_folder_change_set_received_msg (change, info->msg);
-		notify_folder_observers_about (info->self, change);
-		g_object_unref (change);
-		g_object_unref (info->msg);
-	}
-
 	/* thread reference */
 	_tny_camel_folder_unreason (priv);
 	g_object_unref (info->self);
@@ -1636,10 +1627,12 @@
 	tny_idle_stopper_destroy (info->stopper);
 	info->stopper = NULL;
 
-	g_mutex_lock (info->mutex);
-	g_cond_broadcast (info->condition);
-	info->had_callback = TRUE;
-	g_mutex_unlock (info->mutex);
+	if (info->condition) {
+		g_mutex_lock (info->mutex);
+		g_cond_broadcast (info->condition);
+		info->had_callback = TRUE;
+		g_mutex_unlock (info->mutex);
+	}
 
 	return;
 }
@@ -1649,13 +1642,25 @@
 tny_camel_folder_get_msg_async_callback (gpointer thr_user_data)
 {
 	GetMsgInfo *info = (GetMsgInfo *) thr_user_data;
+	TnyFolderChange *change;
+	TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (info->self);
 
+	if (info->msg) 
+	{
+		change = tny_folder_change_new (info->self);
+		tny_folder_change_set_received_msg (change, info->msg);
+		notify_folder_observers_about (info->self, change);
+		g_object_unref (change);
+		g_object_unref (info->msg);
+	}
+
 	if (info->callback)
 		info->callback (info->self, info->cancelled, info->msg, &info->err, info->user_data);
 
 	/* Prevent status callbacks from being called after this
 	 * (can happen because the 2 idle callbacks have different priorities)
 	 * by causing tny_idle_stopper_is_stopped() to return TRUE. */
+
 	tny_idle_stopper_stop (info->stopper);
 
 	return FALSE;
@@ -1687,6 +1692,8 @@
 	GError *err = NULL;
 	CamelOperation *cancel;
 
+	/* TNY TODO: Ensure load_folder here */
+
 	/* This one doesn't use the _tny_camel_account_start_camel_operation 
 	 * infrastructure because it doesn't need to cancel existing operations
 	 * due to a patch to camel-lite allowing messages to be fetched while
@@ -1696,14 +1703,14 @@
 
 	/* To disable parallel getting of messages while summary is being retreived,
 	 * restore this lock (A) */
-
 	/* g_static_rec_mutex_lock (priv->folder_lock); */
 
 	camel_operation_ref (cancel);
 	camel_operation_register (cancel);
 	camel_operation_start (cancel, (char *) "Getting message");
 
-	info->msg = tny_msg_receive_strategy_perform_get_msg (priv->receive_strat, info->self, info->header, &err);
+	info->msg = tny_msg_receive_strategy_perform_get_msg (priv->receive_strat, 
+			info->self, info->header, &err);
 
 	info->cancelled = camel_operation_cancel_check (cancel);
 
@@ -1714,7 +1721,6 @@
 
 	/* To disable parallel getting of messages while summary is being retreived,
 	 * restore this lock (B) */
-
 	/* g_static_rec_mutex_unlock (priv->folder_lock);  */
 
 	info->err = NULL;
@@ -1727,21 +1733,16 @@
 	} else
 		info->err = NULL;
 
+	/* thread reference header */
 	g_object_unref (info->header);
 
 	info->mutex = g_mutex_new ();
 	info->condition = g_cond_new ();
 	info->had_callback = FALSE;
 
-	if (info->callback)
-	{
-		execute_callback (info->depth, G_PRIORITY_DEFAULT, 
-				  tny_camel_folder_get_msg_async_callback, info, 
-				  tny_camel_folder_get_msg_async_destroyer);
-	} else {/* thread reference */
-		_tny_camel_folder_unreason (priv);
-		g_object_unref (info->self);
-	}
+	execute_callback (info->depth, G_PRIORITY_DEFAULT, 
+			  tny_camel_folder_get_msg_async_callback, info, 
+			  tny_camel_folder_get_msg_async_destroyer);
 
 	/* Wait on the queue for the mainloop callback to be finished */
 	g_mutex_lock (info->mutex);
@@ -1762,10 +1763,10 @@
 tny_camel_folder_get_msg_async_cancelled_destroyer (gpointer thr_user_data)
 {
 	GetMsgInfo *info = (GetMsgInfo *) thr_user_data;
-
 	g_error_free (info->err);
 	g_object_unref (info->self);
 	g_slice_free (GetMsgInfo, info);
+	return;
 }
 
 static gboolean
@@ -1773,10 +1774,8 @@
 {
 
 	GetMsgInfo *info = (GetMsgInfo *) thr_user_data;
-
 	if (info->callback)
 		info->callback (info->self, TRUE, NULL, &info->err, info->user_data);
-
 	return FALSE;
 }
 
@@ -1804,6 +1803,7 @@
 	info->status_callback = status_callback;
 	info->user_data = user_data;
 	info->depth = g_main_depth ();
+	info->condition = NULL;
 
 	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, &err, 
 			TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_GET_MSG))
@@ -1827,9 +1827,11 @@
 
 	/* thread reference */
 	_tny_camel_folder_reason (priv);
-	g_object_ref (G_OBJECT (info->self));
-	g_object_ref (G_OBJECT (info->header));
+	g_object_ref (info->self);
 
+	/* thread reference header */
+	g_object_ref (info->header);
+
 	_tny_camel_queue_launch (TNY_FOLDER_PRIV_GET_MSG_QUEUE (priv), 
 		tny_camel_folder_get_msg_async_thread, info);
 
@@ -1885,8 +1887,9 @@
 	TnyMsg *retval = NULL;
 	TnyFolderChange *change;
 
-	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, err, 
-			TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_GET_MSG))
+	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), 
+			priv->account, err, TNY_FOLDER_ERROR, 
+			TNY_FOLDER_ERROR_GET_MSG))
 		return NULL;
 
 	g_assert (TNY_IS_HEADER (header));
@@ -1941,8 +1944,9 @@
 	CamelMessageInfo *info;
 	const gchar *uid;
 
-	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, err, 
-			TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_GET_MSG))
+	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), 
+			priv->account, err, TNY_FOLDER_ERROR, 
+			TNY_FOLDER_ERROR_GET_MSG))
 		return NULL;
 
 	if (!priv->receive_strat) {
@@ -2040,7 +2044,6 @@
 tny_camel_folder_get_id_default (TnyFolder *self)
 {
 	TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
-
 	return priv->folder_name;
 }
 
@@ -2279,10 +2282,10 @@
 	{
 		TnyFolderStoreObserver *observer = TNY_FOLDER_STORE_OBSERVER (tny_iterator_get_current (iter));
 		tny_folder_store_observer_update (observer, change);
-		g_object_unref (G_OBJECT (observer));
+		g_object_unref (observer);
 		tny_iterator_next (iter);
 	}
-	g_object_unref (G_OBJECT (iter));
+	g_object_unref (iter);
 }
 
 static void
@@ -2307,7 +2310,7 @@
 			tny_debug ("tny_folder_copy: observers notify folder-del %s\n", 
 				tny_folder_get_name (evt->fol));
 
-			g_object_unref (G_OBJECT (change));
+			g_object_unref (change);
 		}
 
 		cpy_event_free (evt);
@@ -2329,7 +2332,7 @@
 		else
 			notify_folder_store_observers_about (evt->str, change);
 
-		g_object_unref (G_OBJECT (change));
+		g_object_unref (change);
 
 		tny_debug ("tny_folder_copy: observers notify folder-add %s\n",
 			 tny_folder_get_name (evt->fol));
@@ -2365,7 +2368,6 @@
 				priv->reason_to_live);
 
 		g_propagate_error (err, nerr);
-		/* g_error_free (nerr); */
 		return retc;
 	}
 
@@ -2534,8 +2536,9 @@
 	GError *nerr = NULL;
 	CpyRecRet *cpyr;
 
-	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, err, 
-			TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_COPY))
+	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), 
+			priv->account, err, TNY_FOLDER_ERROR, 
+			TNY_FOLDER_ERROR_COPY))
 		return NULL;
 
 	cpyr = tny_camel_folder_copy_shared (self, into, new_name, del, &nerr, rems, adds);
@@ -2547,10 +2550,8 @@
 	g_slice_free (CpyRecRet, cpyr);
 
 	if (nerr != NULL)
-	{
 		g_propagate_error (err, nerr);
-		/* g_error_free (nerr); */
-	} else
+	else
 		notify_folder_observers_about_copy (adds, rems, del);
 
 	_tny_session_stop_operation (TNY_FOLDER_PRIV_GET_SESSION (priv));
@@ -2590,10 +2591,8 @@
 	CopyFolderInfo *info = (CopyFolderInfo *) thr_user_data;
 
 	if (info->err == NULL)
-	{
 		notify_folder_observers_about_copy (info->adds, info->rems, 
 			info->delete_originals);
-	}
 
 	if (info->new_folder)
 		g_object_unref (info->new_folder);
@@ -2601,7 +2600,6 @@
 	/* thread reference */
 	g_object_unref (info->into);
 	g_object_unref (info->self);
-	/* _tny_camel_folder_unreason (priv); */
 
 	if (info->err)
 		g_error_free (info->err);
@@ -2613,11 +2611,14 @@
 	g_free (info->new_name);
 
 
-	g_mutex_lock (info->mutex);
-	g_cond_broadcast (info->condition);
-	info->had_callback = TRUE;
-	g_mutex_unlock (info->mutex);
+	if (info->condition) {
+		g_mutex_lock (info->mutex);
+		g_cond_broadcast (info->condition);
+		info->had_callback = TRUE;
+		g_mutex_unlock (info->mutex);
+	}
 
+
 	return;
 }
 
@@ -2645,6 +2646,10 @@
 	TnyProgressInfo *info = NULL;
 
 	/* Send back progress data only for these internal operations */
+
+	if (!what)
+		return;
+
 	if ((g_ascii_strcasecmp(what, "Renaming folder")) &&
 	    (g_ascii_strcasecmp(what, "Moving messages")) &&
 	    (g_ascii_strcasecmp(what, "Copying messages"))) 
@@ -2678,10 +2683,10 @@
 
 	_tny_camel_account_start_camel_operation (TNY_CAMEL_ACCOUNT (priv->account), 
 						  tny_camel_folder_copy_async_status, 
-						  info, 
-						  "Copying folder");
+						  info, "Copying folder");
 
-	info->adds = NULL; info->rems = NULL;
+	info->adds = NULL; 
+	info->rems = NULL;
 
 	cpyr = tny_camel_folder_copy_shared (info->self, info->into, 
 			info->new_name, info->delete_originals, &nerr, 
@@ -2699,9 +2704,7 @@
 
 	info->err = NULL;
 	if (nerr != NULL)
-	{
 		g_propagate_error (&info->err, nerr);
-	}
 
 	g_static_rec_mutex_unlock (priv->folder_lock);
 
@@ -2709,15 +2712,9 @@
 	info->condition = g_cond_new ();
 	info->had_callback = FALSE;
 
-	if (info->callback)
-	{
-		execute_callback (info->depth, G_PRIORITY_DEFAULT, 
-				  tny_camel_folder_copy_async_callback, info, 
-				  tny_camel_folder_copy_async_destroyer);
-	} else { /* Thread reference */
-		g_object_unref (info->into);
-		g_object_unref (info->self);
-	}
+	execute_callback (info->depth, G_PRIORITY_DEFAULT, 
+			  tny_camel_folder_copy_async_callback, info, 
+			  tny_camel_folder_copy_async_destroyer);
 
 	/* Wait on the queue for the mainloop callback to be finished */
 	g_mutex_lock (info->mutex);
@@ -2737,12 +2734,12 @@
 tny_camel_folder_copy_async_cancelled_destroyer (gpointer thr_user_data)
 {
 	CopyFolderInfo *info = (CopyFolderInfo *) thr_user_data;
-
 	g_free (info->new_name);
 	g_error_free (info->err);
 	g_object_unref (info->self);
 	g_object_unref (info->into);
 	g_slice_free (CopyFolderInfo, info);
+	return;
 }
 
 static gboolean
@@ -2750,10 +2747,8 @@
 {
 
 	CopyFolderInfo *info = (CopyFolderInfo *) thr_user_data;
-
 	if (info->callback)
 		info->callback (info->self, info->into, TRUE, NULL, &info->err, info->user_data);
-
 	return FALSE;
 }
 
@@ -2785,6 +2780,7 @@
 	info->err = NULL;
 	info->delete_originals = del;
 	info->new_name = g_strdup (new_name);
+	info->condition = NULL;
 
 	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, &err, 
 			TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_COPY))
@@ -2805,10 +2801,10 @@
 	/* Use a ref count because we do not know which of the 2 idle callbacks 
 	 * will be the last, and we can only unref self in the last callback:
 	 * This is destroyed in the idle GDestroyNotify callback. */
+
 	info->stopper = tny_idle_stopper_new();
 
 	/* thread reference */
-/* 	_tny_camel_folder_reason (priv); */
 	g_object_ref (G_OBJECT (info->self));
 	g_object_ref (G_OBJECT (info->into));
 
@@ -2909,10 +2905,12 @@
 	info->stopper = NULL;
 
 
-	g_mutex_lock (info->mutex);
-	g_cond_broadcast (info->condition);
-	info->had_callback = TRUE;
-	g_mutex_unlock (info->mutex);
+	if (info->condition) {
+		g_mutex_lock (info->mutex);
+		g_cond_broadcast (info->condition);
+		info->had_callback = TRUE;
+		g_mutex_unlock (info->mutex);
+	}
 
 	return;
 }
@@ -2921,15 +2919,12 @@
 tny_camel_folder_transfer_msgs_async_callback (gpointer thr_user_data)
 {
 	TransferMsgsInfo *info = thr_user_data;
-
 	if (info->callback)
 		info->callback (info->self, info->cancelled, &info->err, info->user_data);
-
 	/* Prevent status callbacks from being called after this
 	 * (can happen because the 2 idle callbacks have different priorities)
 	 * by causing tny_idle_stopper_is_stopped() to return TRUE. */
 	tny_idle_stopper_stop (info->stopper);
-
 	return FALSE;
 }
 
@@ -2953,8 +2948,9 @@
 	g_assert (TNY_IS_FOLDER (folder_src));
 	g_assert (TNY_IS_FOLDER (folder_dst));
 
-	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, err, 
-			TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_TRANSFER_MSGS))
+	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), 
+			priv->account, err, TNY_FOLDER_ERROR, 
+			TNY_FOLDER_ERROR_TRANSFER_MSGS))
 		return;
 
 	iter = tny_list_create_iterator (headers);
@@ -3304,20 +3300,9 @@
 	info->condition = g_cond_new ();
 	info->had_callback = FALSE;
 
-	/* Call callback function, if it exists */
-	if (info->callback)
-	{
-		execute_callback (info->depth, G_PRIORITY_DEFAULT, 
-				  tny_camel_folder_transfer_msgs_async_callback, info, 
-				  tny_camel_folder_transfer_msgs_async_destroyer);
-	} else { 
-		/* Thread reference */
-		_tny_camel_folder_unreason (priv_src);
-		g_object_unref (G_OBJECT (info->self));
-		g_object_unref (G_OBJECT (info->header_list));
-		_tny_camel_folder_unreason (priv_dst);
-		g_object_unref (G_OBJECT (info->folder_dst));
-	}
+	execute_callback (info->depth, G_PRIORITY_DEFAULT, 
+			  tny_camel_folder_transfer_msgs_async_callback, info, 
+			  tny_camel_folder_transfer_msgs_async_destroyer);
 
 	/* Wait on the queue for the mainloop callback to be finished */
 	g_mutex_lock (info->mutex);
@@ -3337,21 +3322,19 @@
 tny_camel_folder_transfer_msgs_async_cancelled_destroyer (gpointer thr_user_data)
 {
 	TransferMsgsInfo *info = thr_user_data;
-
 	g_error_free (info->err);
 	g_object_unref (info->new_header_list);
 	g_object_unref (info->self);
 	g_slice_free (TransferMsgsInfo, info);
+	return;
 }
 
 static gboolean
 tny_camel_folder_transfer_msgs_async_cancelled_callback (gpointer thr_user_data)
 {
 	TransferMsgsInfo *info = thr_user_data;
-
 	if (info->callback)
 		info->callback (info->self, TRUE, &info->err, info->user_data);
-
 	return FALSE;
 }
 
@@ -3385,6 +3368,7 @@
 	info->user_data = user_data;
 	info->delete_originals = delete_originals;
 	info->depth = g_main_depth ();
+	info->condition = NULL;
 
 	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, &err, 
 			TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_TRANSFER_MSGS))
@@ -3520,9 +3504,10 @@
 	g_mutex_lock (priv->reason_lock);
 	priv->reason_to_live--;
 
-#ifdef DEBUG
+#ifdef DEBUG_EXTRA
 	g_print ("_tny_camel_folder_unreason (%s) : %d\n", 
-		priv->folder_name?priv->folder_name:"(cleared)", priv->reason_to_live);
+		priv->folder_name?priv->folder_name:"(cleared)", 
+			priv->reason_to_live);
 #endif
 
 	if (priv->reason_to_live == 0) 
@@ -3784,8 +3769,11 @@
 	_tny_camel_folder_set_unread_count (folder, info->unread);
 	_tny_camel_folder_set_all_count (folder, info->total);
 	_tny_camel_folder_set_local_size (folder, info->local_size);
+
 	if (!info->name)
-		g_warning ("Creating invalid folder\n");
+		g_critical ("Creating invalid folder. This indicates a problem "
+			    "in the software\n");
+
 	_tny_camel_folder_set_name (folder, info->name);
 	_tny_camel_folder_set_iter (folder, info);
 
@@ -3816,8 +3804,9 @@
 	TnyFolderStoreChange *change;
 	CamelException subex = CAMEL_EXCEPTION_INITIALISER;
 
-	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, err, 
-			TNY_FOLDER_STORE_ERROR, TNY_FOLDER_STORE_ERROR_CREATE_FOLDER))
+	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), 
+			priv->account, err, TNY_FOLDER_STORE_ERROR, 
+			TNY_FOLDER_STORE_ERROR_CREATE_FOLDER))
 		return NULL;
 
 	if (!name || strlen (name) <= 0)
@@ -3955,11 +3944,11 @@
 	TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
 	CamelFolderInfo *iter;
 
-	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, err, 
-			TNY_FOLDER_STORE_ERROR, TNY_FOLDER_STORE_ERROR_GET_FOLDERS))
+	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), 
+			priv->account, err, TNY_FOLDER_STORE_ERROR, 
+			TNY_FOLDER_STORE_ERROR_GET_FOLDERS))
 		return;
 
-
 	if (!priv->iter && priv->iter_parented)
 	{
 		CamelStore *store = priv->store;
@@ -4042,18 +4031,20 @@
 
 	/* thread reference */
 	_tny_camel_folder_unreason (priv);
-	g_object_unref (G_OBJECT (info->self));
-	g_object_unref (G_OBJECT (info->list));
+	g_object_unref (info->self);
+	g_object_unref (info->list);
 
 	if (info->err)
 		g_error_free (info->err);
 
 	_tny_session_stop_operation (info->session);
 
-	g_mutex_lock (info->mutex);
-	g_cond_broadcast (info->condition);
-	info->had_callback = TRUE;
-	g_mutex_unlock (info->mutex);
+	if (info->condition) {
+		g_mutex_lock (info->mutex);
+		g_cond_broadcast (info->condition);
+		info->had_callback = TRUE;
+		g_mutex_unlock (info->mutex);
+	}
 
 	return;
 }
@@ -4062,10 +4053,8 @@
 tny_camel_folder_get_folders_async_callback (gpointer thr_user_data)
 {
 	GetFoldersInfo *info = thr_user_data;
-
 	if (info->callback)
 		info->callback (info->self, info->list, &info->err, info->user_data);
-
 	return FALSE;
 }
 
@@ -4092,19 +4081,10 @@
 	info->condition = g_cond_new ();
 	info->had_callback = FALSE;
 
+	execute_callback (info->depth, G_PRIORITY_DEFAULT, 
+			  tny_camel_folder_get_folders_async_callback, info, 
+			  tny_camel_folder_get_folders_async_destroyer);
 
-	if (info->callback)
-	{
-		execute_callback (info->depth, G_PRIORITY_DEFAULT, 
-				  tny_camel_folder_get_folders_async_callback, info, 
-				  tny_camel_folder_get_folders_async_destroyer);
-	} else {
-		/* thread reference */
-		_tny_camel_folder_unreason (priv);
-		g_object_unref (G_OBJECT (info->self));
-		g_object_unref (G_OBJECT (info->list));
-	}
-
 	/* Wait on the queue for the mainloop callback to be finished */
 	g_mutex_lock (info->mutex);
 	if (!info->had_callback)
@@ -4123,21 +4103,19 @@
 tny_camel_folder_get_folders_async_cancelled_destroyer (gpointer thr_user_data)
 {
 	GetFoldersInfo *info = thr_user_data;
-
 	g_error_free (info->err);
 	g_object_unref (info->self);
 	g_object_unref (info->list);
 	g_slice_free (GetFoldersInfo, info);
+	return;
 }
 
 static gboolean
 tny_camel_folder_get_folders_async_cancelled_callback (gpointer thr_user_data)
 {
 	GetFoldersInfo *info = thr_user_data;
-
 	if (info->callback)
 		info->callback (info->self, info->list, &info->err, info->user_data);
-
 	return FALSE;
 }
 
@@ -4163,6 +4141,7 @@
 	info->user_data = user_data;
 	info->query = query;
 	info->depth = g_main_depth ();
+	info->condition = NULL;
 
 	if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv), priv->account, &err, 
 			TNY_FOLDER_ERROR, TNY_FOLDER_ERROR_REFRESH))
@@ -4219,7 +4198,7 @@
 	if (G_UNLIKELY (!priv->loaded))
 		if (!load_folder (priv))
 			return NULL;
-	
+
 	retval = priv->folder;
 	if (retval)
 		camel_object_ref (CAMEL_OBJECT (retval));
@@ -4235,8 +4214,7 @@
 	return;
 }
 
-typedef struct
-{
+typedef struct {
 	TnyFolder *self;
 	gint unread;
 	gint total;
@@ -4265,7 +4243,6 @@
 	if (do_something)
 		notify_folder_observers_about (self, change);
 
-
 	g_object_unref (change);
 
 	return FALSE;
@@ -4275,10 +4252,9 @@
 tny_camel_folder_poke_status_destroyer (gpointer data)
 {
 	PokeStatusInfo *info = (PokeStatusInfo *) data;
-
 	g_object_unref (info->self);
-
 	g_slice_free (PokeStatusInfo, info);
+	return;
 }
 
 
@@ -4329,6 +4305,7 @@
 	if (folder)
 		g_object_unref (folder);
 
+
 	return NULL;
 }
 
@@ -4353,12 +4330,9 @@
 		{
 			/* Thread reference */
 			g_object_ref (self);
-
 			_tny_camel_queue_launch (TNY_FOLDER_PRIV_GET_QUEUE (priv), 
 				tny_camel_folder_poke_status_thread, self);
 
-			info = NULL;
-
 		} else {
 			if (priv->iter) {
 				info = g_slice_new (PokeStatusInfo);
@@ -4369,14 +4343,12 @@
 	}
 
 
-	if (info)
+	if (info) 
 	{
 		info->self = TNY_FOLDER (g_object_ref (self));
-
 		execute_callback (g_main_depth (), G_PRIORITY_HIGH, 
 				  tny_camel_folder_poke_status_callback, info, 
 				  tny_camel_folder_poke_status_destroyer);
-
 	}
 
 	return;
@@ -4543,6 +4515,7 @@
 	/* iter->uri is a cache.
 	 * Check for strlen(), because camel produces an empty (non-null) 
 	 * uri for POP. */
+
 	if (priv->iter && priv->iter->uri && (strlen (priv->iter->uri) > 0))
 	{
 		retval = g_strdup_printf ("%s", priv->iter->uri);
@@ -4558,13 +4531,12 @@
 		}
 	}
 
-	if (!retval) { /* Strange, a local one?*/
+	if (!retval) { /* Strange, a local one? */
 		g_warning ("tny_folder_get_url_string does not have an "
 				"iter nor account. Using maildir as type.\n");
 		retval = g_strdup_printf ("maildir://%s", priv->folder_name);
 	}
 
-	/* printf ("DEBUG: %s: retval='%s'\n", __FUNCTION__, retval); */
 	return retval;
 }
 
@@ -4609,7 +4581,9 @@
 	TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self);
 
 #ifdef DEBUG
-	g_print ("Finalizing TnyCamelFolder: %s\n", priv->folder_name?priv->folder_name:"(cleared)");
+	g_print ("Finalizing TnyCamelFolder: %s\n", 
+		priv->folder_name?priv->folder_name:"(cleared)");
+
 	if (priv->reason_to_live != 0)
 		g_print ("Finalizing TnyCamelFolder, yet TnyHeader instances "
 		"are still alive: %d\n", priv->reason_to_live);
@@ -4618,12 +4592,13 @@
 	/* Commented because they should not be really needed but some
 	   times they're causing locking problems. TODO: review the
 	   source of this behaviour */
-/* 	g_static_rec_mutex_lock (priv->obs_lock); */
+
+	/* g_static_rec_mutex_lock (priv->obs_lock); */
 	if (priv->observers)
 		g_object_unref (G_OBJECT (priv->observers));
 	if (priv->sobservers)
 		g_object_unref (G_OBJECT (priv->sobservers));
-/* 	g_static_rec_mutex_unlock (priv->obs_lock); */
+	/* g_static_rec_mutex_unlock (priv->obs_lock); */
 
 	g_static_rec_mutex_lock (priv->folder_lock);
 	priv->dont_fkill = FALSE;
Index: libtinymail-camel/tny-camel-account-priv.h
===================================================================
--- libtinymail-camel/tny-camel-account-priv.h	(revision 2535)
+++ libtinymail-camel/tny-camel-account-priv.h	(working copy)
@@ -67,7 +67,7 @@
 	RefreshStatusInfo *csyncop;
 	GList *chooks;
 	TnyConnectionStatus status;
-	gboolean is_connecting;
+	gboolean is_connecting, is_ready;
 };
 
 const CamelService* _tny_camel_account_get_service (TnyCamelAccount *self);
Index: libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-command.c
===================================================================
--- libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-command.c	(revision 2535)
+++ libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-command.c	(working copy)
@@ -1006,8 +1006,8 @@
 			     CamelException *ex)
 {
 	int len = strlen (type), i;
-	char *resp;
-	
+	char *resp = NULL;
+
 	len = strlen (type);
 	
 	for (i = 0; i < response->untagged->len; i++) {
Index: libtinymail-camel/tny-camel-send-queue.c
===================================================================
--- libtinymail-camel/tny-camel-send-queue.c	(revision 2535)
+++ libtinymail-camel/tny-camel-send-queue.c	(working copy)
@@ -162,7 +162,7 @@
 {
 	TnySendQueue *self = (TnySendQueue *) data;
 	TnyCamelSendQueuePriv *priv = TNY_CAMEL_SEND_QUEUE_GET_PRIVATE (self);
-	TnyCamelAccountPriv *apriv = NULL;
+	/* TnyCamelAccountPriv *apriv = NULL; */
 	TnyFolder *sentbox, *outbox;
 	guint i = 0, length = 0;
 	TnyList *list;
@@ -172,9 +172,9 @@
 	priv->is_running = TRUE;
 	priv->creating_spin = FALSE;
 
-	apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (priv->trans_account);
+/*	apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (priv->trans_account);
 	if (apriv)
-		tny_session_camel_join_connecting (apriv->session);
+		tny_session_camel_join_connecting (apriv->session); */
 
 	list = tny_simple_list_new ();
 
@@ -388,9 +388,8 @@
 tny_camel_send_queue_join_worker (TnyCamelSendQueue *self)
 {
 	TnyCamelSendQueuePriv *priv = TNY_CAMEL_SEND_QUEUE_GET_PRIVATE (self);
-	TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (priv->trans_account);
 
-	if (!apriv->session->priv->conthread && priv->thread)
+	if (priv->thread)
 		g_thread_join (priv->thread);
 }
 
Index: libtinymail-camel/tny-camel-store-account-priv.h
===================================================================
--- libtinymail-camel/tny-camel-store-account-priv.h	(revision 2535)
+++ libtinymail-camel/tny-camel-store-account-priv.h	(working copy)
@@ -20,8 +20,11 @@
  * Boston, MA 02111-1307, USA.
  */
 
+#include <tny-session-camel.h>
 #include <tny-camel-store-account.h>
+
 #include "tny-camel-queue-priv.h"
+#include "tny-session-camel-priv.h"
 
 typedef struct _TnyCamelStoreAccountPriv TnyCamelStoreAccountPriv;
 
@@ -40,5 +43,6 @@
 	(G_TYPE_INSTANCE_GET_PRIVATE ((o), TNY_TYPE_CAMEL_STORE_ACCOUNT, TnyCamelStoreAccountPriv))
 
 void _tny_camel_store_account_emit_conchg_signal (TnyCamelStoreAccount *self);
+void _tny_camel_store_account_queue_going_online (TnyCamelStoreAccount *self, TnySessionCamel *session, gboolean online, go_online_callback_func err_func, gpointer user_data);
 
 #endif
Index: libtinymail-camel/tny-session-camel-priv.h
===================================================================
--- libtinymail-camel/tny-session-camel-priv.h	(revision 2535)
+++ libtinymail-camel/tny-session-camel-priv.h	(working copy)
@@ -9,21 +9,25 @@
 	gpointer account_store;
 	gboolean interactive, prev_constat;
 	guint connchanged_signal;
-	GList *current_accounts;
+
+	GHashTable *current_accounts;
+	GStaticRecMutex *current_accounts_lock;
+
 	gchar *camel_dir;
 	gboolean in_auth_function, is_connecting;
-	gboolean async_connect;
 	TnyLockable *ui_lock;
-	GMutex *conlock, *queue_lock;
-	GThread *conthread;
+	GMutex *queue_lock;
+
 	gboolean stop_now, initialized;
-	gboolean is_inuse, background_thread_running;
+	gboolean is_inuse;
 	GList *regged_queues;
 };
 
-void _tny_session_camel_add_account_1 (TnySessionCamel *self, TnyCamelAccount *account);
-void _tny_session_camel_add_account_2 (TnySessionCamel *self, TnyCamelAccount *account);
-void _tny_session_camel_forget_account (TnySessionCamel *self, TnyCamelAccount *account);
+typedef void (*go_online_callback_func) (TnySessionCamel *self, TnyCamelAccount *account, GError *err, gpointer user_data);
+void _tny_session_camel_register_account (TnySessionCamel *self, TnyCamelAccount *account);
+void _tny_session_camel_activate_account (TnySessionCamel *self, TnyCamelAccount *account);
+void _tny_session_camel_unregister_account (TnySessionCamel *self, TnyCamelAccount *account);
+
 void _tny_session_camel_reg_queue (TnySessionCamel *self, TnyCamelSendQueue *queue);
 void _tny_session_camel_unreg_queue (TnySessionCamel *self, TnyCamelSendQueue *queue);
 
Index: libtinymail-camel/tny-session-camel.c
===================================================================
--- libtinymail-camel/tny-session-camel.c	(revision 2535)
+++ libtinymail-camel/tny-session-camel.c	(working copy)
@@ -63,6 +63,65 @@
 
 static void tny_session_camel_forget_password (CamelSession *, CamelService *, const char *, const char *, CamelException *);
 
+
+
+/* Hey Rob, look here! This gets called when the password is needed. It can have
+ * been implemented by the app developer without any Gtk+ code. Sometimes, 
+ * however, it will launch Gtk+ code. For example the first time the password
+ * is needed.
+ *
+ * This happens in a thread, so does the tny_session_camel_forget_password. The 
+ * thread is always the queue thread of the account. 
+ *
+ * This is number #1 */
+
+
+typedef struct
+{
+	TnySessionCamel *self;
+	TnyAccount *account;
+	gchar *prompt, *retval;
+	gboolean cancel;
+	TnyGetPassFunc func;
+
+	GCond* condition;
+	gboolean had_callback;
+	GMutex *mutex;
+
+} HadToWaitForPasswordInfo;
+
+
+static gboolean
+get_password_idle_func (gpointer user_data)
+{
+	HadToWaitForPasswordInfo *info = (HadToWaitForPasswordInfo *) user_data;
+	TnySessionCamel *self = info->self;
+	TnyAccount *account = info->account;
+	TnyGetPassFunc func = info->func;
+
+	tny_lockable_lock (self->priv->ui_lock);
+	info->retval = func (account, info->prompt, &info->cancel);
+	tny_lockable_unlock (self->priv->ui_lock);
+
+	return FALSE;
+}
+
+static void
+get_password_destroy_func (gpointer user_data)
+{
+	HadToWaitForPasswordInfo *info = (HadToWaitForPasswordInfo *) user_data;
+
+	g_object_unref (info->account);
+	camel_object_unref (info->self);
+
+	g_mutex_lock (info->mutex);
+	g_cond_broadcast (info->condition);
+	info->had_callback = TRUE;
+	g_mutex_unlock (info->mutex);
+
+	return;
+}
+
 static char *
 tny_session_camel_get_password (CamelSession *session, CamelService *service, const char *domain,
 		const char *prompt, const char *item, guint32 flags, CamelException *ex)
@@ -71,12 +130,13 @@
 	TnyGetPassFunc func;
 	TnyAccount *account;
 	gboolean freeprmpt = FALSE, cancel = FALSE;
-	gchar *retval = NULL, *prmpt = (gchar*)prompt;
+	gchar *retval = NULL, *prmpt = (gchar*) prompt;
 	TnyCamelAccountPriv *apriv = NULL;
 
 	account = service->data;
 	if (account)
 	{
+		HadToWaitForPasswordInfo *info = NULL;
 
 		func = tny_account_get_pass_func (account);
 
@@ -101,56 +161,118 @@
 		apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (account);
 		apriv->in_auth = TRUE;
 
-		tny_lockable_lock (self->priv->ui_lock);
-		retval = func (account, prmpt, &cancel);
-		tny_lockable_unlock (self->priv->ui_lock);
+		info = g_slice_new (HadToWaitForPasswordInfo);
 
+		info->mutex = g_mutex_new ();
+		info->condition = g_cond_new ();
+		info->had_callback = FALSE;
+
+		camel_object_ref (self);
+		info->self = self;
+		info->account = TNY_ACCOUNT (g_object_ref (account));
+		info->prompt = prmpt;
+		info->func = func;
+		info->cancel = FALSE;
+		info->retval = NULL;
+
+		g_idle_add_full (G_PRIORITY_DEFAULT, 
+			get_password_idle_func, info, 
+			get_password_destroy_func);
+
+		/* Wait on the queue for the mainloop callback to be finished */
+		g_mutex_lock (info->mutex);
+		if (!info->had_callback)
+			g_cond_wait (info->condition, info->mutex);
+		g_mutex_unlock (info->mutex);
+
+		g_mutex_free (info->mutex);
+		g_cond_free (info->condition);
+
+		cancel = info->cancel;
+		retval = info->retval;
+
+		g_slice_free (HadToWaitForPasswordInfo, info);
+
 		apriv->in_auth = FALSE;
 
 		if (freeprmpt)
 			g_free (prmpt);
 	}
 
-	if (cancel || retval == NULL) {
-
+	if (cancel || retval == NULL) 
+	{
 		GError *err = NULL;
-
 		_tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (account), FALSE, &err);
-
 		if (err)
 			g_error_free (err);
-
 		camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
 			_("You cancelled when you had to enter a password"));
+		if (retval)
+			g_free (retval);
 		retval = NULL;
 	}
 
 	return retval;
 }
 
-/**
- * tny_session_camel_set_ui_locker:
- * @self: a #TnySessionCamel instance
- * @ui_lock: a #TnyLockable instance 
+
+/* Hey Rob, look here! This gets called when the password was wrong. It can
+ * but usually wont use Gtk+ code by the implementer of the function pointer.
+ * Usually the application developer will "forget" the password here. So that
+ * The next request for a password gives the user a password dialog box. 
  *
- * Set the user interface toolkit locker. The lock and unlock methods of this
- * locker should be implemented with the lock and unlock functionality of your
- * user interface toolkit.
+ * That request will happen by the tny_session_camel_get_password function. This
+ * happens in a thread, so does the tny_session_camel_get_password. The thread
+ * is always the queue thread of the account. 
  *
- * Good examples are gdk_threads_enter () and gdk_threads_leave () in gtk+.
- **/
-void 
-tny_session_camel_set_ui_locker (TnySessionCamel *self, TnyLockable *ui_lock)
+ * This is number #2 */
+
+
+
+typedef struct
 {
-	TnySessionCamelPriv *priv = self->priv;
-	if (priv->ui_lock)
-		g_object_unref (G_OBJECT (priv->ui_lock));
-	priv->ui_lock = TNY_LOCKABLE (g_object_ref (ui_lock));
-	return;
+	TnySessionCamel *self;
+	TnyAccount *account;
+	TnyForgetPassFunc func;
+
+	GCond* condition;
+	gboolean had_callback;
+	GMutex *mutex;
+
+} HadToWaitForForgetInfo;
+
+
+static gboolean
+forget_password_idle_func (gpointer user_data)
+{
+	HadToWaitForForgetInfo *info = (HadToWaitForForgetInfo *) user_data;
+	TnySessionCamel *self = info->self;
+	TnyAccount *account = info->account;
+	TnyForgetPassFunc func = info->func;
+
+	tny_lockable_lock (self->priv->ui_lock);
+	func (account);
+	tny_lockable_unlock (self->priv->ui_lock);
+
+	return FALSE;
 }
 
+static void
+forget_password_destroy_func (gpointer user_data)
+{
+	HadToWaitForForgetInfo *info = (HadToWaitForForgetInfo *) user_data;
 
+	g_object_unref (info->account);
+	camel_object_unref (info->self);
 
+	g_mutex_lock (info->mutex);
+	g_cond_broadcast (info->condition);
+	info->had_callback = TRUE;
+	g_mutex_unlock (info->mutex);
+
+	return;
+}
+
 static void
 tny_session_camel_forget_password (CamelSession *session, CamelService *service, const char *domain, const char *item, CamelException *ex)
 {
@@ -162,33 +284,151 @@
 
 	if (account)
 	{
+		HadToWaitForForgetInfo *info = NULL;
+
 		func = tny_account_get_forget_pass_func (account);
 
 		if (!func)
 			return;
 
-		tny_lockable_lock (self->priv->ui_lock);
-		func (account);
-		tny_lockable_unlock (self->priv->ui_lock);
+		info = g_slice_new (HadToWaitForForgetInfo);
+
+		info->mutex = g_mutex_new ();
+		info->condition = g_cond_new ();
+		info->had_callback = FALSE;
+
+		camel_object_ref (self);
+		info->self = self;
+		info->account = TNY_ACCOUNT (g_object_ref (account));
+		info->func = func;
+
+		g_idle_add_full (G_PRIORITY_DEFAULT, 
+			forget_password_idle_func, info, 
+			forget_password_destroy_func);
+
+		/* Wait on the queue for the mainloop callback to be finished */
+		g_mutex_lock (info->mutex);
+		if (!info->had_callback)
+			g_cond_wait (info->condition, info->mutex);
+		g_mutex_unlock (info->mutex);
+
+		g_mutex_free (info->mutex);
+		g_cond_free (info->condition);
+
+		g_slice_free (HadToWaitForForgetInfo, info);
+
 	}
 
 	return;
 }
 
+/* This is a wrapper for the alerting. Called by on_account_connect_done and
+ * tny_session_camel_alert_user (see below for both) */
+
+typedef struct
+{
+	TnySessionCamel *self;
+	TnyAccount *account;
+	TnyAlertType tnytype;
+	gboolean question, retval;
+	GError *err;
+
+	GCond* condition;
+	gboolean had_callback;
+	GMutex *mutex;
+
+} HadToWaitForAlertInfo;
+
+
 static gboolean
-tny_session_camel_do_an_error (TnySessionCamel *self, TnyAccount *account, TnyAlertType tnytype, gboolean question, GError *err)
+alert_idle_func (gpointer user_data)
 {
-	return tny_account_store_alert (
+	HadToWaitForAlertInfo *info = user_data;
+	TnySessionCamel *self = info->self;
+	TnyAccount *account = info->account;
+
+	tny_lockable_lock (self->priv->ui_lock);
+
+	info->retval = tny_account_store_alert (
 		(TnyAccountStore*) self->priv->account_store, 
-		account, tnytype, question, (const GError *) err);
+		account, info->tnytype, info->question, 
+		(const GError *) info->err);
+
+	tny_lockable_unlock (self->priv->ui_lock);
+
+	return FALSE;
 }
 
+static void
+alert_destroy_func (gpointer user_data)
+{
+	HadToWaitForAlertInfo *info = (HadToWaitForAlertInfo *) user_data;
+
+	if (info->account)
+		g_object_unref (info->account);
+	camel_object_unref (info->self);
+
+	g_mutex_lock (info->mutex);
+	g_cond_broadcast (info->condition);
+	info->had_callback = TRUE;
+	g_mutex_unlock (info->mutex);
+
+	return;
+}
+
+static gboolean
+tny_session_camel_do_an_error (TnySessionCamel *self, TnyAccount *account, TnyAlertType tnytype, gboolean question, GError *err)
+{
+	HadToWaitForAlertInfo *info = NULL;
+	gboolean retval = FALSE;
+
+	info = g_slice_new (HadToWaitForAlertInfo);
+
+	info->mutex = g_mutex_new ();
+	info->condition = g_cond_new ();
+	info->had_callback = FALSE;
+
+	camel_object_ref (self);
+	info->self = self;
+	info->account = account?TNY_ACCOUNT (g_object_ref (account)):NULL;
+	info->tnytype = tnytype;
+	info->question = question;
+	info->err = err;
+	info->retval = FALSE;
+
+	g_idle_add_full (G_PRIORITY_DEFAULT, 
+		alert_idle_func, info, 
+		alert_destroy_func);
+
+	/* Wait on the queue for the mainloop callback to be finished */
+	g_mutex_lock (info->mutex);
+	if (!info->had_callback)
+		g_cond_wait (info->condition, info->mutex);
+	g_mutex_unlock (info->mutex);
+
+	g_mutex_free (info->mutex);
+	g_cond_free (info->condition);
+
+	retval = info->retval;
+
+	g_slice_free (HadToWaitForAlertInfo, info);
+
+	return retval;
+}
+
 /* tny_session_camel_alert_user will for example be called by camel when SSL is on and 
-   camel_session_get_service is issued (for example TnyCamelTransportAccount and
-   TnyCamelStore account issue this function). Its implementation is often done
-   with GUI components (it should therefore not be called from a thread). This
-   is a known issue (and if someone fixes this, please remove this warning) */
+ * camel_session_get_service is issued (for example TnyCamelTransportAccount and
+ * TnyCamelStore account issue this function). Its implementation is often done
+ * with GUI components (it should therefore not be called from a thread). */
 
+/* Hey Rob, look here! This is an alert that will be launched from a thread. 
+ * usually the queue thread of the account (I think always, but I have to verify
+ * this before making a statement out of it). The user sometimes has to answer 
+ * this question. For example with a Yes or a No. The typical example is the 
+ * SSL question and error reporting when the connection is lost) 
+ *
+ * This is number #3 */
+
 static gboolean
 tny_session_camel_alert_user (CamelSession *session, CamelSessionAlertType type, CamelException *ex, gboolean cancel, CamelService *service)
 {
@@ -196,8 +436,8 @@
 	TnySessionCamelPriv *priv = self->priv;
 	gboolean retval = FALSE;
 	GError *err = NULL;
+	TnyAccount *account = NULL;
 
-	TnyAccount *account = NULL;
 	if (service && service->data)
 		account = TNY_ACCOUNT (service->data);
 
@@ -221,27 +461,47 @@
 
 		if (ex->id == CAMEL_EXCEPTION_USER_CANCEL)
 			g_set_error (&err, TNY_ACCOUNT_STORE_ERROR, 
-				TNY_ACCOUNT_STORE_ERROR_CANCEL_ALERT, "The connecting was canceled");
-		else {
+				TNY_ACCOUNT_STORE_ERROR_CANCEL_ALERT, 
+				"The connecting was canceled");
+		else
 			g_set_error (&err, TNY_ACCOUNT_STORE_ERROR, 
 				_tny_camel_account_get_tny_error_code_for_camel_exception_id (ex), 
 				camel_exception_get_description (ex));
-		}
 
-		tny_lockable_lock (self->priv->ui_lock);
+		retval = tny_session_camel_do_an_error (self, account, tnytype, 
+			TRUE, err);
 
-		TnyAccount *account = NULL; /* TODO. */
-		retval = tny_session_camel_do_an_error (self, account, tnytype, TRUE, err);
-
-		tny_lockable_unlock (self->priv->ui_lock);
-
-		g_error_free (err);
+		if (err)
+			g_error_free (err);
 	}
 
 	return retval;
 }
 
 
+
+/**
+ * tny_session_camel_set_ui_locker:
+ * @self: a #TnySessionCamel instance
+ * @ui_lock: a #TnyLockable instance 
+ *
+ * Set the user interface toolkit locker. The lock and unlock methods of this
+ * locker should be implemented with the lock and unlock functionality of your
+ * user interface toolkit.
+ *
+ * Good examples are gdk_threads_enter () and gdk_threads_leave () in gtk+.
+ **/
+void 
+tny_session_camel_set_ui_locker (TnySessionCamel *self, TnyLockable *ui_lock)
+{
+	TnySessionCamelPriv *priv = self->priv;
+	if (priv->ui_lock)
+		g_object_unref (G_OBJECT (priv->ui_lock));
+	priv->ui_lock = TNY_LOCKABLE (g_object_ref (ui_lock));
+	return;
+}
+
+
 CamelFolder *
 mail_tool_uri_to_folder (CamelSession *session, const char *uri, guint32 flags, CamelException *ex)
 {
@@ -359,20 +619,6 @@
 	return;
 }
 
-/**
- * tny_session_camel_set_async_connecting:
- * @self: a #TnySessionCamel object
- * @enable: Whether or not to asynchronously connect
- *
- * Set connection strategy
- **/
-void 
-tny_session_camel_set_async_connecting (TnySessionCamel *self, gboolean enable)
-{
-	g_mutex_lock (self->priv->conlock);
-	self->priv->async_connect = enable;
-	g_mutex_unlock (self->priv->conlock);
-}
 
 
 static void
@@ -385,12 +631,18 @@
 	priv->initialized = FALSE;
 	priv->stop_now = FALSE;
 	priv->regged_queues = NULL;
-	priv->background_thread_running = FALSE;
 	priv->is_inuse = FALSE;
-	priv->conlock = g_mutex_new ();
 	priv->queue_lock = g_mutex_new ();
-	priv->conthread = NULL;
-	priv->current_accounts = NULL;
+
+	/* I know it would be better to have a hashtable that does reference
+	 * counting. But then you'll get embraced references, which gobject
+	 * can't really handle (unless doing it with a weak reference) */
+
+	priv->current_accounts = g_hash_table_new_full (g_str_hash, g_direct_equal, 
+					g_free, NULL);
+
+	priv->current_accounts_lock = g_new0 (GStaticRecMutex, 1);
+	g_static_rec_mutex_init (priv->current_accounts_lock);
 	priv->prev_constat = FALSE;
 	priv->device = NULL;
 	priv->camel_dir = NULL;
@@ -398,198 +650,117 @@
 	priv->camel_dir = NULL;
 	priv->in_auth_function = FALSE;
 	priv->is_connecting = FALSE;
-	priv->async_connect = TRUE;
 
 	return;
 }
 
-typedef struct
-{
-	TnyDevice *device;
-	gboolean online, as_thread;
-	gpointer user_data;
-	TnySessionCamelPriv *priv;
-} BackgroundConnectInfo;
 
-static gboolean
-background_connect_idle (gpointer data)
+/* Happens at tny_camel_account_set_session. This does very few things, actually.
+ * Maybe we can factor this away and make the tny_camel_account_set_session not
+ * required anymore? Though, the account will always need to know what the session
+ * is. So we'd have to find another way to let the account know about this ... */
+
+void 
+_tny_session_camel_register_account (TnySessionCamel *self, TnyCamelAccount *account)
 {
-	BackgroundConnectInfo *info = data;
-	TnySessionCamel *self = info->user_data;
+	TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (account);
 	TnySessionCamelPriv *priv = self->priv;
 
-	if (priv->account_store)
-	{
-		g_signal_emit (priv->account_store, 
-			tny_account_store_signals [TNY_ACCOUNT_STORE_ACCOUNTS_RELOADED], 0);
-		g_signal_emit (priv->account_store,
-			tny_account_store_signals [TNY_ACCOUNT_STORE_CONNECTING_FINISHED], 0);
-	}
+	if (apriv->cache_location)
+		g_free (apriv->cache_location);
+	apriv->cache_location = g_strdup (priv->camel_dir);
 
-	return FALSE;
-}
-
-
-
-static void
-background_connect_destroy (gpointer data)
-{
-	BackgroundConnectInfo *info = data;
-
-	g_object_unref (G_OBJECT (info->device));
-	g_slice_free (BackgroundConnectInfo, data);
-
 	return;
 }
 
-
-
 static void
-foreach_account_set_connectivity (gpointer data, gpointer udata)
+on_account_connect_done (TnySessionCamel *self, TnyCamelAccount *account, GError *err, gpointer user_data)
 {
-	BackgroundConnectInfo *info = udata;
-	TnySessionCamel *self = info->user_data;
-	
-	if (data && TNY_IS_CAMEL_ACCOUNT (data))
-	{
-		TnyCamelAccount *account = TNY_CAMEL_ACCOUNT (data);
-		
-		GError *err = NULL;
-		TnyCamelAccountPriv *apriv = NULL;
+	TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (account);
 
-		/* We don't go online on transport accounts, yet */
-		if (TNY_IS_CAMEL_TRANSPORT_ACCOUNT (account))
-		{
-			g_signal_emit (account, 
-				tny_camel_account_signals [TNY_CAMEL_ACCOUNT_SET_ONLINE_HAPPENED], 0, info->online);
-			return;
-		}
+	/* This one happens when a account is finished with connecting. On 
+	 * failure, err is not NULL on success it is NULL. This happens in a
+	 * thread: the queue thread of @account. */
 
-		apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (account);
+	/* Hey Rob, look here! This will happen when you have an error. This
+	 * "do_an_error" thing will invoke the alert_func from a thread. */
 
-		apriv->is_connecting = TRUE;
 
-		_tny_camel_account_try_connect (account, FALSE /* info->online */, &err);
+	/* We set the account to ready, so that tny_account_is_ready returns TRUE
+	 * from now on. _tny_session_camel_activate_account caused this callback
+	 * to happen (either successful or non-successful, this happens for each
+	 * account that is internally ready) */
 
-		if (err == NULL)
-			_tny_camel_account_set_online (account, info->online, &err);
+	apriv->is_ready = TRUE;
 
-		if (err != NULL) 
-		{
-			if (self->priv->account_store)
-			{
-				if (info->as_thread)
-					tny_lockable_lock (self->priv->ui_lock);
+	if (err)
+		tny_session_camel_do_an_error (self, TNY_ACCOUNT (account), 
+			TNY_ALERT_TYPE_ERROR, FALSE, err);
 
-				tny_session_camel_do_an_error (self, TNY_ACCOUNT (account), TNY_ALERT_TYPE_ERROR, FALSE, err);
-
-				if (info->as_thread)
-					tny_lockable_unlock (self->priv->ui_lock);
-			}
-			g_error_free (err);
-		}
-
-		apriv->is_connecting = FALSE;
-
-	}
+	return;
 }
 
-typedef struct {
-	BackgroundConnectInfo *info;
-	TnyCamelAccount *account;
-} AccGoOnlineInfo;
 
-static gpointer
-account_go_online (gpointer data)
+static void 
+tny_session_queue_going_online_for_account (TnySessionCamel *self, TnyCamelAccount *account, gboolean online)
 {
-	AccGoOnlineInfo *ainfo = (AccGoOnlineInfo *) data;
-	TnySessionCamel *self = ainfo->info->user_data;
-	TnySessionCamelPriv *priv = self->priv;
 
-	priv->is_connecting = TRUE;
+	/* So this is that wrapper that I talked about (see below). In case we 
+	 * are a store account, this means that we need to throw the request to
+	 * go online to the account's queue. This is implemented in a protected
+	 * method in TnyCamelStoreAccount. Go take a look! */
 
-	foreach_account_set_connectivity (ainfo->account, ainfo->info);
+	if (TNY_IS_CAMEL_STORE_ACCOUNT (account)) 
+		_tny_camel_store_account_queue_going_online (
+			TNY_CAMEL_STORE_ACCOUNT (account), self, online, 
+			on_account_connect_done, NULL);
 
-	priv->is_connecting = FALSE;
+	/* Else, if it's a transport account, we don't have any transport 
+	 * account implementations that actually need to go online at this 
+	 * moment yet. At the moment of transferring the first message, the
+	 * current implementations will automatically connect themselves. */
 
-	camel_object_unref (ainfo->info->user_data);
-	g_object_unref (ainfo->account);
-
-	g_idle_add_full (G_PRIORITY_HIGH, 
-		background_connect_idle, 
-		ainfo->info, background_connect_destroy);
-
-	g_slice_free (AccGoOnlineInfo, ainfo);
-	/* ainfo->info is freed in the background_connect_destroy */
-
-	priv->conthread = NULL;
-
-	g_thread_exit (NULL);
-	return NULL;
+	if (TNY_IS_CAMEL_TRANSPORT_ACCOUNT (account))
+	{
+		g_signal_emit (account, 
+			tny_camel_account_signals [TNY_CAMEL_ACCOUNT_SET_ONLINE_HAPPENED], 0, online);
+		return;
+	}
 }
 
+/* This happens when the password function of the account is set. It will after 
+ * registering the account for future connection-changes, already set the online
+ * state of it to the current connectivity setting of the device */
 
-void 
-_tny_session_camel_add_account_1 (TnySessionCamel *self, TnyCamelAccount *account)
-{
-	TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (account);
-	TnySessionCamelPriv *priv = self->priv;
-
-	if (apriv->cache_location)
-		g_free (apriv->cache_location);
-	apriv->cache_location = g_strdup (priv->camel_dir);
-	priv->current_accounts = g_list_prepend (priv->current_accounts, account);
-}
-
 void
-_tny_session_camel_add_account_2 (TnySessionCamel *self, TnyCamelAccount *account)
+_tny_session_camel_activate_account (TnySessionCamel *self, TnyCamelAccount *account)
 {
-	TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (account);
 	TnySessionCamelPriv *priv = self->priv;
-	gboolean doit = FALSE;
 
-	if (priv->initialized)
-	{
-		g_mutex_lock (priv->conlock);
-		doit = (priv->conthread == NULL);
-		g_mutex_unlock (priv->conlock);
-	}
+	g_static_rec_mutex_lock (priv->current_accounts_lock);
 
-	if (priv->initialized && !priv->background_thread_running && doit)
-	{
-		if (priv->device && TNY_IS_DEVICE (priv->device))
-		{
-			AccGoOnlineInfo *ainfo = g_slice_new (AccGoOnlineInfo);
-			ainfo->info = g_slice_new (BackgroundConnectInfo);
+	/* It would indeed be better to add a reference here. But then you'll
+	 * get embraced references at some point. We'll get rid of the instance
+	 * in the hashtable before the finalization of it, take a look at the
+	 * unregister stuff below. */
 
-			ainfo->info->online = tny_device_is_online (priv->device);
-			ainfo->info->as_thread = TRUE;
-			ainfo->info->priv = priv;
+	g_hash_table_insert (priv->current_accounts, 
+			g_strdup (tny_account_get_id (TNY_ACCOUNT (account))),
+			account);
+	g_static_rec_mutex_unlock (priv->current_accounts_lock);
 
-			ainfo->info->device = g_object_ref (priv->device);
-			camel_object_ref (self);
-			ainfo->info->user_data = self;
-			ainfo->account = TNY_CAMEL_ACCOUNT (g_object_ref (account));
+	tny_session_queue_going_online_for_account (self, account, 
+		tny_device_is_online (priv->device));
 
-			camel_session_set_online ((CamelSession *) self, TRUE); 
+	return;
+}
 
-			if (priv->account_store)
-			{
-				g_signal_emit (priv->account_store,
-					tny_account_store_signals [TNY_ACCOUNT_STORE_CONNECTING_STARTED], 0);
-			}
 
-			g_mutex_lock (priv->conlock);
-			if (priv->conthread)
-				g_thread_join (priv->conthread);
-			priv->conthread = g_thread_create (account_go_online, ainfo, TRUE, NULL);
-			g_mutex_unlock (priv->conlock);
-		}
-	}
-}
+/* This happens when an account gets finalized. We more or less simply get rid
+ * of the instance in the hashtable. */
 
 void 
-_tny_session_camel_forget_account (TnySessionCamel *self, TnyCamelAccount *account)
+_tny_session_camel_unregister_account (TnySessionCamel *self, TnyCamelAccount *account)
 {
 	TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (account);
 	TnySessionCamelPriv *priv = self->priv;
@@ -598,147 +769,100 @@
 		g_free (apriv->cache_location);
 	apriv->cache_location = NULL;
 
-	priv->current_accounts = g_list_remove (priv->current_accounts, account);
+	g_static_rec_mutex_lock (priv->current_accounts_lock);
+	g_hash_table_remove (priv->current_accounts, 
+		tny_account_get_id (TNY_ACCOUNT (account)));
+	g_static_rec_mutex_unlock (priv->current_accounts_lock);
 
 	return;
 }
 
+typedef struct {
+	TnySessionCamel *self;
+	gboolean online;
+} ConChangedForEachInfo;
 
-
-
-static gpointer 
-background_connect_thread (gpointer data)
+static void 
+tny_session_camel_connection_changed_for_each (gpointer key, gpointer value, gpointer user_data)
 {
-	BackgroundConnectInfo *info = data;
-	TnySessionCamel *self = info->user_data;
-	TnySessionCamelPriv *priv = self->priv;
+	ConChangedForEachInfo *info = (ConChangedForEachInfo *) user_data;
 
-	if (priv->background_thread_running) {
-		g_thread_exit (NULL);
-		return NULL;
-	}
+	/* For each registered account, we'll set its online state. Throwing it
+	 * in its queue is implemented in the TnyCamelStoreAccount btw. For now,
+	 * because it's shared with the account registration, this is a wrapper */
 
-	priv->background_thread_running = TRUE;
+	tny_session_queue_going_online_for_account (info->self, 
+		TNY_CAMEL_ACCOUNT (value), info->online);
 
-	if (priv->stop_now) 
-		goto stop_now;
-
-	priv->is_connecting = TRUE;
-
-	if (priv->current_accounts && priv->prev_constat != info->online && priv->account_store) 
-	{
-		GList *copy = priv->current_accounts;
-		while (copy)
-		{
-			if (priv->stop_now) 
-				goto stop_now;
-			foreach_account_set_connectivity (copy->data, info);
-			if (priv->stop_now) 
-				goto stop_now;
-			copy = g_list_next (copy);
-		}
-	}
-
-stop_now:
-
-	priv->is_connecting = FALSE;
-
-	g_idle_add_full (G_PRIORITY_HIGH, 
-		background_connect_idle, 
-		info, background_connect_destroy);
-
-	priv->prev_constat = info->online;
-
-	priv->conthread = NULL;
-	priv->background_thread_running = FALSE;
-
-	priv->stop_now = FALSE;
-
-	g_thread_exit (NULL);
-	return NULL;
+	return;
 }
 
-static gboolean
-do_background_connect_thread (gpointer data)
-{
-	BackgroundConnectInfo *info = data;
-	TnySessionCamel *self = info->user_data;
-	TnySessionCamelPriv *priv = self->priv;
+/* In case our TnyDevice's connection_changed event happened. We'll set all
+ * registered accounts to the proper online state here. Because these accounts
+ * all register their connecting on their own queue, it's not detectable when
+ * connecting got finished. They also all start doing their connecting stuff
+ * in parallel. Quite difficult to know when all are finished with that. 
+ *
+ * In stead we provide components, like the TnyGtkFolderStoreTreeModel, that can
+ * cope with connection changes. For example: they'll load-in new folders as 
+ * soon as it's known that the account went online. No more accounts-reloaded
+ * things as it's far more fine grained this way ... */
 
-	/* g_mutex_lock (info->priv->conlock); */
-	info->priv->conthread = g_thread_create (background_connect_thread, data, TRUE, NULL);
-	/* g_mutex_unlock (info->priv->conlock); */
-
-	return FALSE;
-}
-
 static void
 tny_session_camel_connection_changed (TnyDevice *device, gboolean online, gpointer user_data)
 {
 	TnySessionCamel *self = user_data;
 	TnySessionCamelPriv *priv = self->priv;
-	BackgroundConnectInfo *info;
-	gboolean inf;
+	ConChangedForEachInfo *info = NULL;
 
-	inf = priv->in_auth_function;
-	if (inf) return;
 
-	info = g_slice_new (BackgroundConnectInfo);
+	/* Maybe we can remove this check after Rob is finished with throwing  
+	 * the questions in the GMainLoop. I'm leaving it here for now ... */
 
-	info->device = g_object_ref (G_OBJECT (device));
+	if (priv->in_auth_function)
+		return;
+
+	info = g_slice_new (ConChangedForEachInfo);
+
 	info->online = online;
-	info->user_data = user_data;
-	info->priv = priv;
+	info->self = self;
 
+
+	/* This Camel API exists, I haven't yet figured out what exactly it does
+	 * or change in terms of behaviour. */
+
 	camel_session_set_online ((CamelSession *) self, online); 
 
+
+	/* As said, we can issue this signal. We can't issue when connecting 
+	 * actually finished: that's because all accounts register getting 
+	 * connected on their own queues. So it'll all happen in parallel and
+	 * a little bit less in control as when we would dedicate a thread to it,
+	 * and in a serialized way get all accounts connected (the old way) */
+
 	if (priv->account_store)
-	{
 		g_signal_emit (priv->account_store,
 			tny_account_store_signals [TNY_ACCOUNT_STORE_CONNECTING_STARTED], 0);
-	}
 
+	g_static_rec_mutex_lock (priv->current_accounts_lock);
+	/* So let's look above, at that for_each function ... */
+	g_hash_table_foreach (priv->current_accounts, 
+		tny_session_camel_connection_changed_for_each, info);
+	g_static_rec_mutex_unlock (priv->current_accounts_lock);
 
-	if (priv->async_connect) 
-	{
-		gboolean doit = FALSE;
+	g_slice_free (ConChangedForEachInfo, info);
 
-		info->as_thread = TRUE;
-
-		if (!priv->conthread)
-			do_background_connect_thread (info);
-
-	} else {
-		info->as_thread = FALSE;
-		background_connect_thread (info);
-	}
-
 	return;
 }
 
-/**
- * tny_session_camel_join_connecting
- * @self: a #TnySessionCamel object
- * 
- * Join the connection thread
- **/ 
-void 
-tny_session_camel_join_connecting (TnySessionCamel *self)
-{
-	TnySessionCamelPriv *priv = self->priv;
 
-	g_mutex_lock (priv->conlock);
-	if (priv->conthread)
-		g_thread_join (priv->conthread);
-	g_mutex_unlock (priv->conlock);
-}
-
 /**
  * tny_session_camel_set_initialized:
  * @self: the #TnySessionCamel instance
  *
- * This method must be called one the initial accounts are created in your
- * #TnyAccountStore implementation.
+ * This method must be called once the initial accounts are created in your
+ * #TnyAccountStore implementation and should indicate that the initialization
+ * of your initial accounts is completed.
  **/
 void 
 tny_session_camel_set_initialized (TnySessionCamel *self)
@@ -788,6 +912,9 @@
 			priv->connchanged_signal);
 	}
 
+	/* TNY TODO: proper reference counting here please! Note that we can't
+	 * have embraced references either. So be careful! */
+
 	priv->device = device;
 
 	return;
@@ -882,6 +1009,10 @@
 	TnySessionCamel *self = (TnySessionCamel*)object;
 	TnySessionCamelPriv *priv = self->priv;
 
+	g_static_rec_mutex_lock (priv->current_accounts_lock);
+	g_hash_table_destroy (priv->current_accounts);
+	g_static_rec_mutex_unlock (priv->current_accounts_lock);
+
 	g_mutex_lock (priv->queue_lock);
 	g_list_free (priv->regged_queues);
 	priv->regged_queues = NULL;
@@ -899,8 +1030,8 @@
 	if (priv->camel_dir)
 		g_free (priv->camel_dir);
 
-	g_mutex_free (priv->conlock);
 	g_mutex_free (priv->queue_lock);
+	g_static_rec_mutex_free (priv->current_accounts_lock);
 
 	g_slice_free (TnySessionCamelPriv, self->priv);
 
@@ -922,7 +1053,6 @@
 	camel_session_class->thread_msg_free = tny_session_camel_ms_thread_msg_free;
 	camel_session_class->thread_status = tny_session_camel_ms_thread_status;
 
-
 	return;
 }
 
Index: libtinymail-camel/tny-camel-queue.c
===================================================================
--- libtinymail-camel/tny-camel-queue.c	(revision 2535)
+++ libtinymail-camel/tny-camel-queue.c	(working copy)
@@ -102,7 +102,7 @@
 		g_mutex_lock (queue->lock);
 		if (first)
 			queue->list = g_list_delete_link (queue->list, first);
-
+	
 		if (g_list_length (queue->list) == 0) {
 			queue->thread = NULL;
 			queue->stopped = TRUE;
@@ -114,7 +114,7 @@
 		if (item)
 			g_slice_free (QueueItem, item);
 	}
-
+	
 	queue->thread = NULL;
 	queue->stopped = TRUE;
 	g_object_unref (queue);
@@ -136,13 +136,19 @@
 
 	g_mutex_lock (queue->lock);
 	queue->list = g_list_append (queue->list, item);
-	g_mutex_unlock (queue->lock);
 
-	if (!queue->thread) {
+	if (queue->stopped) {
+		GError *err = NULL;
 		queue->stopped = FALSE;
+		g_object_ref (queue);
 		queue->thread = g_thread_create (thread_main_func, 
-			g_object_ref (queue), TRUE, NULL);
+			queue, TRUE, &err);
+		if (err) {
+			queue->stopped = TRUE;	
+		}
 	}
+	g_mutex_unlock (queue->lock);
+
 }
 
 static void 
@@ -164,7 +170,7 @@
 {
 	TnyCamelQueue *self = (TnyCamelQueue*)instance;
 
-	self->stopped = FALSE;
+	self->stopped = TRUE;
 	self->list = NULL;
 	self->thread = NULL;
 	self->lock = g_mutex_new ();
Index: libtinymail-camel/tny-camel-store-account.c
===================================================================
--- libtinymail-camel/tny-camel-store-account.c	(revision 2535)
+++ libtinymail-camel/tny-camel-store-account.c	(working copy)
@@ -83,10 +83,10 @@
 	{
 		TnyFolderStoreObserver *observer = TNY_FOLDER_STORE_OBSERVER (tny_iterator_get_current (iter));
 		tny_folder_store_observer_update (observer, change);
-		g_object_unref (G_OBJECT (observer));
+		g_object_unref (observer);
 		tny_iterator_next (iter);
 	}
-	g_object_unref (G_OBJECT (iter));
+	g_object_unref (iter);
 }
 
 static gboolean
@@ -97,7 +97,7 @@
 
 	g_signal_emit (G_OBJECT (self), 
 		tny_account_signals [TNY_ACCOUNT_CONNECTION_STATUS_CHANGED], 
-		0, apriv->status);
+			0, apriv->status);
 
 	return FALSE;
 }
@@ -276,6 +276,7 @@
 _tny_camel_store_account_emit_conchg_signal (TnyCamelStoreAccount *self)
 {
 	/* tny_camel_store_account_do_emit (self); */
+	return;
 }
 
 static void 
@@ -410,10 +411,7 @@
 					"Unknown error while connecting");
 			}
 		} else {
-
 			tny_camel_store_account_do_emit (TNY_CAMEL_STORE_ACCOUNT (self));
-
-			/* tny_camel_account_set_online (self, apriv->connected); */
 		}
 
 		g_static_rec_mutex_unlock (apriv->service_lock);
@@ -587,8 +585,6 @@
 	g_object_unref (priv->queue);
 	g_object_unref (priv->msg_queue);
 
-	/* Disco store ? */
-
 	(*parent_class->finalize) (object);
 
 	return;
@@ -613,8 +609,6 @@
 
 	g_assert (TNY_IS_CAMEL_FOLDER (folder));
 
-	/* TNY TODO: Support non-TnyCamelFolder TnyFolder implementations too */
-
 	store = CAMEL_STORE (apriv->service);
 
 	if (camel_exception_is_set (&ex)) 
@@ -639,7 +633,6 @@
 	{
 		g_warning ("Trying to remove an invalid folder\n");
 		g_static_rec_mutex_unlock (aspriv->factory_lock);
-
 		return;
 	}
 
@@ -792,10 +785,8 @@
 	if (nerr != NULL)
 		g_propagate_error (err, nerr);
 
-
 	_tny_session_stop_operation (apriv->session);
 
-
 	return;
 }
 
@@ -946,8 +937,6 @@
 		TnyFolder *fnd = (TnyFolder*) copy->data;
 		const gchar *name = tny_folder_get_id (fnd);
 
-		/* printf ("COMPARE: [%s] [%s]\n", name, full_name); */
-
 		if (name && full_name && !strcmp (name, full_name))
 		{
 			folder = TNY_CAMEL_FOLDER (g_object_ref (G_OBJECT (fnd)));
@@ -961,8 +950,6 @@
 		folder = TNY_CAMEL_FOLDER (_tny_camel_folder_new ());
 		priv->managed_folders = g_list_prepend (priv->managed_folders, folder);
 
-		/* printf ("CREATE: %s\n", full_name); */
-
 		*was_new = TRUE;
 	}
 
@@ -1108,8 +1095,8 @@
 	GetFoldersInfo *info = thr_user_data;
 
 	/* gidle reference */
-	g_object_unref (G_OBJECT (info->self));
-	g_object_unref (G_OBJECT (info->list));
+	g_object_unref (info->self);
+	g_object_unref (info->list);
 
 	if (info->err)
 		g_error_free (info->err);
@@ -1128,13 +1115,34 @@
 tny_camel_store_account_get_folders_async_callback (gpointer thr_user_data)
 {
 	GetFoldersInfo *info = thr_user_data;
-
 	if (info->callback)
 		info->callback (info->self, info->list,&info->err, info->user_data);
-
 	return FALSE;
 }
 
+
+/**
+ * When using a #GMainLoop this method will execute a callback using
+ * g_idle_add_full.  Note that without a #GMainLoop, the callbacks
+ * could happen in a worker thread (depends on who call it) at an
+ * unknown moment in time (check your locking in this case).
+ */
+static void
+execute_callback (gint depth, 
+		  gint priority,
+		  GSourceFunc idle_func,
+		  gpointer data, 
+		  GDestroyNotify destroy_func)
+{
+	if (depth > 0){
+		g_idle_add_full (priority, idle_func, data, destroy_func);
+	} else {
+		idle_func (data);
+		destroy_func (data);
+	}
+}
+
+
 static gpointer 
 tny_camel_store_account_get_folders_async_thread (gpointer thr_user_data)
 {
@@ -1156,21 +1164,9 @@
 	info->condition = g_cond_new ();
 	info->had_callback = FALSE;
 
-	if (info->callback)
-	{
-		if (info->depth > 0)
-		{
-			g_idle_add_full (G_PRIORITY_HIGH, 
-				tny_camel_store_account_get_folders_async_callback, 
-				info, tny_camel_store_account_get_folders_async_destroyer);
-		} else {
-			tny_camel_store_account_get_folders_async_callback (info);
-			tny_camel_store_account_get_folders_async_destroyer (info);
-		}
-	} else {
-		g_object_unref (G_OBJECT (info->self));
-		g_object_unref (G_OBJECT (info->list));
-	}
+	execute_callback (info->depth, G_PRIORITY_DEFAULT, 
+			  tny_camel_store_account_get_folders_async_callback, info, 
+			  tny_camel_store_account_get_folders_async_destroyer);
 
 	/* Wait on the queue for the mainloop callback to be finished */
 	g_mutex_lock (info->mutex);
@@ -1190,22 +1186,20 @@
 tny_camel_store_account_get_folders_async_cancelled_destroyer (gpointer thr_user_data)
 {
 	GetFoldersInfo *info = thr_user_data;
-
 	/* gidle references */
 	g_object_unref (info->self);
 	g_object_unref (info->list);
 	g_error_free (info->err);
 	g_slice_free (GetFoldersInfo, info);
+	return;
 }
 
 static gboolean
 tny_camel_store_account_get_folders_async_cancelled_callback (gpointer thr_user_data)
 {
 	GetFoldersInfo *info = thr_user_data;
-
 	if (info->callback)
 		info->callback (info->self, info->list, &info->err, info->user_data);
-
 	return FALSE;
 }
 
@@ -1244,24 +1238,19 @@
 			g_object_ref (info->self);
 			g_object_ref (info->list);
 
-			if (info->depth > 0){
-				g_idle_add_full (G_PRIORITY_DEFAULT, 
-						 tny_camel_store_account_get_folders_async_cancelled_callback, info,
-						 tny_camel_store_account_get_folders_async_cancelled_destroyer);
-			} else {
-				tny_camel_store_account_get_folders_async_cancelled_callback (info);
-				tny_camel_store_account_get_folders_async_cancelled_destroyer (info);
-			}
+			execute_callback (info->depth, G_PRIORITY_DEFAULT, 
+				tny_camel_store_account_get_folders_async_cancelled_callback, info,
+				tny_camel_store_account_get_folders_async_cancelled_destroyer);
 		}
 		g_error_free (err);
 		return;
 	}
 
 	/* thread reference */
-	g_object_ref (G_OBJECT (info->self));
-	g_object_ref (G_OBJECT (info->list)); 
+	g_object_ref (info->self);
+	g_object_ref (info->list); 
 	if (info->query)
-		g_object_ref (G_OBJECT (info->query));
+		g_object_ref (info->query);
 
 	_tny_camel_queue_launch (priv->queue, 
 			tny_camel_store_account_get_folders_async_thread, info);
@@ -1441,8 +1430,6 @@
 
 	if (strcasestr (url_string, "maildir"))
 	{
-		// maildir:/home/xxx/.modest/local_folders#New%20folder/1183044323.16675_6.mindcrime_2_S_2_S
-
 		str = strchr (url_string, '#');
 		if (str && strlen (str) > 1)
 		{
@@ -1546,6 +1533,108 @@
 	return retval;
 }
 
+
+
+typedef struct {
+	TnySessionCamel *session;
+	TnyCamelStoreAccount *self;
+	gboolean online;
+	go_online_callback_func done_func;
+	gpointer user_data;
+} GoingOnlineInfo;
+
+static gpointer 
+tny_camel_store_account_queue_going_online_thread (gpointer thr_user_data)
+{
+	GoingOnlineInfo *info = (GoingOnlineInfo*) thr_user_data;
+	TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (info->self);
+	GError *err = NULL;
+
+	/* So this happens in the queue thread. There's only one such thread
+	 * for each TnyCamelStoreAccount active at any given moment in time. 
+	 * This means that operations on the queue, while this is happening,
+	 * must wait. */
+
+	/* The info->done_func points to on_account_connect_done in the 
+	 * TnySessionCamel implementation. Or to the set_online_done handler.
+	 * Go take a look! */
+
+	apriv->is_connecting = TRUE;
+
+	/* This is one of those functions that our hero, Rob, is going to 
+	 * refactor/rename to something that does make sense :-). Isn't that
+	 * true Rob? */
+
+	_tny_camel_account_try_connect (TNY_CAMEL_ACCOUNT (info->self), 
+			FALSE, &err);
+
+	if (err) {
+		info->done_func (info->session, TNY_CAMEL_ACCOUNT (info->self), err, info->user_data);
+		g_error_free (err);
+	} else {
+
+		/* This one actually sets the account to online. Although Rob 
+		 * is probably going to improve all this. Right *poke*? */
+
+		_tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (info->self), 
+			info->online, &err);
+
+		if (err) {
+			info->done_func (info->session, 
+				TNY_CAMEL_ACCOUNT (info->self), err, info->user_data);
+			g_error_free (err);
+		} else
+			info->done_func (info->session, 
+				TNY_CAMEL_ACCOUNT (info->self), NULL, info->user_data);
+
+	}
+
+	apriv->is_connecting = FALSE;
+
+	/* Thread reference */
+	camel_object_unref (info->session);
+	g_object_unref (info->self);
+
+	return NULL;
+}
+
+/* This is that protected implementation that will request to go online, on the
+ * queue of this account @self. Each TnyCamelStoreAccount has two queues: One 
+ * queue is dedicated to getting messages. The other, the default queue, is
+ * dedicated to any other operation. Including getting itself connected with an 
+ * actual server (that can be both a POP or an IMAP server, depending on the 
+ * url-string and/or proto setting of @self). */
+
+void
+_tny_camel_store_account_queue_going_online (TnyCamelStoreAccount *self, TnySessionCamel *session, gboolean online, go_online_callback_func done_func, gpointer user_data)
+{
+	GoingOnlineInfo *info = NULL;
+	GError *err = NULL;
+	TnyCamelAccountPriv *apriv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self);
+	TnyCamelStoreAccountPriv *priv = TNY_CAMEL_STORE_ACCOUNT_GET_PRIVATE (self);
+
+	/* Idle info for the callbacks */
+	info = g_slice_new0 (GoingOnlineInfo);
+
+	info->session = session;
+	info->self = self;
+	info->done_func = done_func;
+	info->online = online;
+	info->user_data = user_data;
+
+	/* thread reference */
+	g_object_ref (info->self);
+	camel_object_ref (info->session);
+
+
+	/* It's indeed a very typical queue operation */
+
+	_tny_camel_queue_launch (priv->queue, 
+		tny_camel_store_account_queue_going_online_thread, info);
+
+	return;
+}
+
 static void
 tny_folder_store_init (gpointer g, gpointer iface_data)
 {
Index: libtinymail-camel/tny-session-camel.h
===================================================================
--- libtinymail-camel/tny-session-camel.h	(revision 2535)
+++ libtinymail-camel/tny-session-camel.h	(working copy)
@@ -51,8 +51,6 @@
 void tny_session_camel_set_account_store (TnySessionCamel *self, TnyAccountStore *account_store);
 void tny_session_camel_set_device (TnySessionCamel *self, TnyDevice *device);
 void tny_session_camel_set_ui_locker (TnySessionCamel *self, TnyLockable *ui_lock);
-void tny_session_camel_join_connecting (TnySessionCamel *self);
-void tny_session_camel_set_async_connecting (TnySessionCamel *self, gboolean enable);
 
 void tny_session_camel_set_initialized (TnySessionCamel *self);
 
Index: libtinymail-camel/tny-camel-account.c
===================================================================
--- libtinymail-camel/tny-camel-account.c	(revision 2535)
+++ libtinymail-camel/tny-camel-account.c	(working copy)
@@ -696,7 +696,7 @@
 	camel_object_ref (session);
 	priv->session = session;
 
-	_tny_session_camel_add_account_1 (session, self);
+	_tny_session_camel_register_account (session, self);
 
 	TNY_CAMEL_ACCOUNT_GET_CLASS (self)->prepare_func (self, FALSE, FALSE);
 
@@ -886,7 +886,7 @@
 		reconf_if, TRUE);
 
 	if (priv->session)
-		_tny_session_camel_add_account_2 (priv->session, TNY_CAMEL_ACCOUNT (self));
+		_tny_session_camel_activate_account (priv->session, TNY_CAMEL_ACCOUNT (self));
 
 	g_static_rec_mutex_unlock (priv->service_lock);
 
@@ -1121,6 +1121,7 @@
 	TnyCamelAccount *self = (TnyCamelAccount *)instance;
 	TnyCamelAccountPriv *priv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self);
 
+	priv->is_ready = FALSE;
 	priv->is_connecting = FALSE;
 	priv->in_auth = FALSE;
 	priv->csyncop = NULL;
@@ -1159,24 +1160,9 @@
 	return;
 }
 
-/**
- * tny_camel_account_set_online:
- * @self: a #TnyCamelAccount object
- * @online: whether or not the account is online
- * @err: a #GError instance or NULL
- *
- * Set the connectivity status of an account.
- * Setting this to FALSE means that the account will not attempt to use the network, 
- * and will use only the cache.
- * Setting this to TRUE means that the account may use the network to provide up-to-date 
- * information.
- *
- **/
-void 
-tny_camel_account_set_online (TnyCamelAccount *self, gboolean online, GError **err)
-{
-	TNY_CAMEL_ACCOUNT_GET_CLASS (self)->set_online_func (self, online, err);
-}
+/* The is the protected version that will actually set it online. This should
+ * always happen in a thread. In fact, it will always happen in the operations
+ * queue of @self (else it's a bug). */
 
 void 
 _tny_camel_account_set_online (TnyCamelAccount *self, gboolean online, GError **err)
@@ -1321,54 +1307,170 @@
 }
 
 
-typedef struct {
-	TnyCamelAccount *self;
-	gboolean online;
-	GError **err;
-	GMainLoop *loop;
-} SetOnlineInfo;
 
-static gpointer
-set_online_thread (gpointer data)
+
+
+/**
+ * tny_camel_account_set_online:
+ * @self: a #TnyCamelAccount object
+ * @online: whether or not the account is online
+ * @callback: a callback when the account went online
+ *
+ * Set the connectivity status of an account. Setting this to FALSE means that 
+ * the account will not attempt to use the network, and will use only the cache.
+ * Setting this to TRUE means that the account may use the network to 
+ * provide up-to-date information.
+ *
+ * The @callback will be invoke as soon as the account is actually online. It's
+ * guaranteed that the @callback will happen in the mainloop, if available.
+ *
+ **/
+void 
+tny_camel_account_set_online (TnyCamelAccount *self, gboolean online, TnyCamelSetOnlineCallback callback)
 {
-	SetOnlineInfo *info = (SetOnlineInfo *) data;
+	TNY_CAMEL_ACCOUNT_GET_CLASS (self)->set_online_func (self, online, callback);
+}
 
-	_tny_camel_account_set_online (info->self, info->online, info->err);
+typedef struct
+{
+	TnyCamelAccount *account;
+	GError *err;
+	TnyCamelSetOnlineCallback callback;
 
-	if (g_main_loop_is_running (info->loop))
-		g_main_loop_quit (info->loop);
+	GCond* condition;
+	gboolean had_callback;
+	GMutex *mutex;
 
-	g_thread_exit (NULL);
-	return NULL;
+} OnSetOnlineInfo;
+
+gboolean 
+on_set_online_done_idle_func (gpointer data)
+{
+	OnSetOnlineInfo *info = (OnSetOnlineInfo *) data;
+	if (info->callback)
+		info->callback (info->account, info->err);
+	return FALSE;
 }
 
+static void 
+on_set_online_done_destroy_func (gpointer data)
+{
+	OnSetOnlineInfo *info = (OnSetOnlineInfo *) data;
+
+	/* We copied it, so we must also free it */
+	if (info->err)
+		g_error_free (info->err);
+
+	/* Thread reference */
+	g_object_unref (info->account);
+
+	if (info->condition) {
+		g_mutex_lock (info->mutex);
+		g_cond_broadcast (info->condition);
+		info->had_callback = TRUE;
+		g_mutex_unlock (info->mutex);
+	}
+
+	return;
+}
+
+/**
+ * When using a #GMainLoop this method will execute a callback using
+ * g_idle_add_full.  Note that without a #GMainLoop, the callbacks
+ * could happen in a worker thread (depends on who call it) at an
+ * unknown moment in time (check your locking in this case).
+ */
+static void
+execute_callback (gint depth, 
+		  gint priority,
+		  GSourceFunc idle_func,
+		  gpointer data, 
+		  GDestroyNotify destroy_func)
+{
+	if (depth > 0){
+		g_idle_add_full (priority, idle_func, data, destroy_func);
+	} else {
+		idle_func (data);
+		destroy_func (data);
+	}
+}
+
+static void 
+on_set_online_done (TnySessionCamel *self, TnyCamelAccount *account, GError *err, gpointer user_data)
+{
+	OnSetOnlineInfo *info = g_slice_new (OnSetOnlineInfo);
+
+	/* Thread reference */
+	info->account = TNY_CAMEL_ACCOUNT (g_object_ref (account));
+
+	/* We must copy the err because this context will destroy it! */
+	if (err)
+		info->err = g_error_copy (err); 
+	else
+		info->err = NULL;
+
+	info->callback = (TnyCamelSetOnlineCallback) user_data;
+
+	info->mutex = g_mutex_new ();
+	info->condition = g_cond_new ();
+	info->had_callback = FALSE;
+
+	execute_callback (/* info->depth */ 10, G_PRIORITY_HIGH, 
+		on_set_online_done_idle_func, 
+		info, on_set_online_done_destroy_func);
+
+	/* Wait on the queue for the mainloop callback to be finished */
+	g_mutex_lock (info->mutex);
+	if (!info->had_callback)
+		g_cond_wait (info->condition, info->mutex);
+	g_mutex_unlock (info->mutex);
+
+	g_mutex_free (info->mutex);
+	g_cond_free (info->condition);
+
+	g_slice_free (OnSetOnlineInfo, info);
+
+	return;
+}
+
 void 
-tny_camel_account_set_online_default (TnyCamelAccount *self, gboolean online, GError **err)
+tny_camel_account_set_online_default (TnyCamelAccount *self, gboolean online, TnyCamelSetOnlineCallback callback)
 {
-	if (g_main_depth () != 0)
+
+	/* In case we  are a store account, this means that we need to throw the 
+	 * request to go online to the account's queue. */
+
+	if (TNY_IS_CAMEL_STORE_ACCOUNT (self))
 	{
-		/* We are being called from the mainnloop */
-		SetOnlineInfo *info = g_slice_new (SetOnlineInfo);
-		GThread *thread = NULL;
+		TnyCamelAccountPriv *priv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self);
+		TnySessionCamel *session = priv->session;
 
-		info->self = TNY_CAMEL_ACCOUNT (g_object_ref (self));
-		info->online = online;
-		info->err = err;
-		info->loop = g_main_loop_new (NULL, FALSE);
+		_tny_camel_store_account_queue_going_online (
+			TNY_CAMEL_STORE_ACCOUNT (self), session, online, 
+			on_set_online_done, (gpointer) callback);
+	}
 
-		thread = g_thread_create (set_online_thread, info, TRUE, NULL);
 
-		g_main_loop_run (info->loop);
+	/* Else, if it's a transport account, we don't have any transport 
+	 * account implementations that actually need to go online at this 
+	 * moment yet. At the moment of transferring the first message, the
+	 * current implementations will automatically connect themselves. */
 
-		g_main_loop_unref (info->loop);
-		g_object_unref (info->self);
-		g_slice_free (SetOnlineInfo, info);
+	if (TNY_IS_CAMEL_TRANSPORT_ACCOUNT (self))
+	{
+		g_signal_emit (self, 
+			tny_camel_account_signals [TNY_CAMEL_ACCOUNT_SET_ONLINE_HAPPENED], 0, online);
+		return;
+	}
+}
 
-	} else
-		_tny_camel_account_set_online (self, online, err);
+static gboolean
+tny_camel_account_is_ready (TnyAccount *self)
+{
+	TnyCamelAccountPriv *priv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self);
+	return priv->is_ready;
 }
 
-
 static void
 tny_camel_account_finalize (GObject *object)
 {
@@ -1387,7 +1489,7 @@
 	}
 
 	if (priv->session) {
-		_tny_session_camel_forget_account (priv->session, (TnyCamelAccount*) object);    
+		_tny_session_camel_unregister_account (priv->session, (TnyCamelAccount*) object);    
 		camel_object_unref (priv->session);
 	}
 	_tny_camel_account_start_camel_operation (self, NULL, NULL, NULL);
@@ -1480,6 +1582,7 @@
 	klass->matches_url_string_func = tny_camel_account_matches_url_string;
 	klass->start_operation_func = tny_camel_account_start_operation;
 	klass->stop_operation_func =  tny_camel_account_stop_operation;
+	klass->is_ready_func = tny_camel_account_is_ready;
 
 	return;
 }
@@ -1668,7 +1771,7 @@
 			g_object_unref (pair);
 		}
 		
-		iter = g_list_next (iter);	
+		iter = g_list_next (iter);
 	}
 	g_list_free (authtypes);
 	authtypes = NULL;
@@ -1740,6 +1843,8 @@
 tny_camel_account_get_supported_secure_authentication (TnyCamelAccount *self, TnyCamelGetSupportedSecureAuthCallback callback, TnyStatusCallback status_callback, gpointer user_data)
 { 
 	TnyCamelAccountPriv *priv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self);
+	GetSupportedAuthInfo *info = NULL;
+
 	g_return_if_fail (callback);
 	g_return_if_fail (priv->session);
 
@@ -1764,7 +1869,7 @@
 
 
 	/* Idle info for the status callback: */
-	GetSupportedAuthInfo *info = g_slice_new (GetSupportedAuthInfo);
+	info = g_slice_new (GetSupportedAuthInfo);
 	info->session = priv->session;
 	info->err = NULL;
 	info->self = self;
Index: libtinymail-camel/tny-camel-account.h
===================================================================
--- libtinymail-camel/tny-camel-account.h	(revision 2535)
+++ libtinymail-camel/tny-camel-account.h	(working copy)
@@ -47,7 +47,9 @@
 
 extern guint tny_camel_account_signals [TNY_CAMEL_ACCOUNT_LAST_SIGNAL];
 
+typedef void (*TnyCamelSetOnlineCallback) (TnyCamelAccount *account, GError *err);
 
+
 struct _TnyCamelAccount
 {
 	GObject parent;
@@ -88,7 +90,7 @@
 
 
 	void (*add_option_func) (TnyCamelAccount *self, const gchar *option);
-	void (*set_online_func) (TnyCamelAccount *self, gboolean online, GError **err);
+	void (*set_online_func) (TnyCamelAccount *self, gboolean online, TnyCamelSetOnlineCallback callback);
 
 	/* Abstract methods */
 	void (*prepare_func) (TnyCamelAccount *self, gboolean recon_if, gboolean reservice);
@@ -102,7 +104,7 @@
 
 void tny_camel_account_add_option (TnyCamelAccount *self, const gchar *option);
 void tny_camel_account_set_session (TnyCamelAccount *self, TnySessionCamel *session);
-void tny_camel_account_set_online (TnyCamelAccount *self, gboolean online, GError **err);
+void tny_camel_account_set_online (TnyCamelAccount *self, gboolean online, TnyCamelSetOnlineCallback callback);
 
 
 typedef void (*TnyCamelGetSupportedSecureAuthCallback) (TnyCamelAccount *self, gboolean cancelled, TnyList *auth_types, GError **err, gpointer user_data);
Index: bindings/python/tinymailmodule.c
===================================================================
--- bindings/python/tinymailmodule.c	(revision 2535)
+++ bindings/python/tinymailmodule.c	(working copy)
@@ -1,7 +1,7 @@
 #include <pygobject.h>
  
 void pytinymail_register_classes (PyObject *d); 
-void pytinymail_add_constants(PyObject *module, const gchar *strip_prefix);
+/*void pytinymail_add_constants(PyObject *module, const gchar *strip_prefix);*/
 extern PyMethodDef pytinymail_functions[];
 
 DL_EXPORT(void)
@@ -15,7 +15,7 @@
     d = PyModule_GetDict (m);
  
     pytinymail_register_classes (d);
-    pytinymail_add_constants (m, "TNY_");
+    /*pytinymail_add_constants (m, "TNY_");*/
        
     if (PyErr_Occurred ()) {
         Py_FatalError ("can't initialise module tinymail");
Index: libtinymailui-gtk/tny-gtk-folder-store-tree-model.h
===================================================================
--- libtinymailui-gtk/tny-gtk-folder-store-tree-model.h	(revision 2535)
+++ libtinymailui-gtk/tny-gtk-folder-store-tree-model.h	(working copy)
@@ -59,7 +59,6 @@
 	GtkTreeStore parent;
 	GList *first;
 	GMutex *iterator_lock;
-	gboolean is_async;
 	TnyFolderStoreQuery *query;
 	GList *store_observables, *folder_observables;
 };
@@ -71,7 +70,7 @@
 
 GType tny_gtk_folder_store_tree_model_get_type (void);
 GType tny_gtk_folder_store_tree_model_column_get_type (void);
-GtkTreeModel* tny_gtk_folder_store_tree_model_new (gboolean async, TnyFolderStoreQuery *query);
+GtkTreeModel* tny_gtk_folder_store_tree_model_new (TnyFolderStoreQuery *query);
 
 void tny_gtk_folder_store_tree_model_prepend (TnyGtkFolderStoreTreeModel *self, TnyFolderStore* item, const gchar *root_name);
 void tny_gtk_folder_store_tree_model_append (TnyGtkFolderStoreTreeModel *self, TnyFolderStore* item, const gchar *root_name);
Index: libtinymailui-gtk/tny-gtk-header-list-model.c
===================================================================
--- libtinymailui-gtk/tny-gtk-header-list-model.c	(revision 2535)
+++ libtinymailui-gtk/tny-gtk-header-list-model.c	(working copy)
@@ -814,7 +814,7 @@
 	return;
 }
 
-#ifdef DEBUG
+#ifdef DEBUG_EXTRA
 static void forea (gpointer u, gpointer o)
 {
 	g_print ("TnyGtkHeaderListModel::finalize unrefs hdr to: %d\n", ((GObject *)u)->ref_count);
@@ -844,7 +844,7 @@
 
 	remove_del_timeouts (self);
 
-#ifdef DEBUG
+#ifdef DEBUG_EXTRA
 	g_ptr_array_foreach (priv->items, (GFunc) forea, NULL);
 #else
 	g_ptr_array_foreach (priv->items, (GFunc) g_object_unref, NULL);
Index: libtinymailui-gtk/tny-gtk-folder-store-tree-model.c
===================================================================
--- libtinymailui-gtk/tny-gtk-folder-store-tree-model.c	(revision 2535)
+++ libtinymailui-gtk/tny-gtk-folder-store-tree-model.c	(working copy)
@@ -29,6 +29,7 @@
 #include <tny-folder-store.h>
 #include <tny-simple-list.h>
 
+#include <tny-store-account.h>
 #include <tny-folder-store-change.h>
 #include <tny-folder-store-observer.h>
 #include <tny-folder-change.h>
@@ -39,86 +40,10 @@
 #include "tny-gtk-folder-store-tree-model-iterator-priv.h"
 
 static GObjectClass *parent_class = NULL;
-static void recurse_folders_async (TnyGtkFolderStoreTreeModel *self, TnyFolderStore *store, GtkTreeIter *parent_tree_iter);
 
 typedef void (*treeaddfunc) (GtkTreeStore *tree_store, GtkTreeIter *iter, GtkTreeIter *parent);
 
-
-typedef struct {
-	GtkTreeIter *parent_tree_iter;
-	TnyGtkFolderStoreTreeModel *self;
-} AsyncHelpr;
-
 static void
-recurse_get_folders_callback (TnyFolderStore *self, TnyList *folders, GError **err, gpointer user_data)
-{
-	AsyncHelpr *hlrp = user_data;
-	TnyIterator *iter = tny_list_create_iterator (folders);
-	TnyGtkFolderStoreTreeModel *me = (TnyGtkFolderStoreTreeModel*) self;
-
-	while (!tny_iterator_is_done (iter))
-	{
-		GtkTreeStore *model = GTK_TREE_STORE (hlrp->self);
-		TnyFolderStore *folder = (TnyFolderStore*) tny_iterator_get_current (iter);
-		GtkTreeIter *tree_iter = gtk_tree_iter_copy (hlrp->parent_tree_iter);
-
-		tny_folder_add_observer (TNY_FOLDER (folder), TNY_FOLDER_OBSERVER (self));
-		tny_folder_store_add_observer (TNY_FOLDER_STORE (folder), TNY_FOLDER_STORE_OBSERVER (self));
-		me->folder_observables = g_list_prepend (me->folder_observables, folder);
-		me->store_observables = g_list_prepend (me->store_observables, folder);
-
-		gtk_tree_store_append (model, tree_iter, hlrp->parent_tree_iter);
-
-		/* This adds a reference count to folder too. When it gets removed, that
-		   reference count is decreased automatically by the gtktreestore infra-
-		   structure. */
-
-		gtk_tree_store_set (model, tree_iter,
-			TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN, 
-			tny_folder_get_name (TNY_FOLDER (folder)),
-			TNY_GTK_FOLDER_STORE_TREE_MODEL_UNREAD_COLUMN, 
-			tny_folder_get_unread_count (TNY_FOLDER (folder)),
-			TNY_GTK_FOLDER_STORE_TREE_MODEL_ALL_COLUMN, 
-			tny_folder_get_all_count (TNY_FOLDER (folder)),
-			TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN,
-			tny_folder_get_folder_type (TNY_FOLDER (folder)),
-			TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN,
-			folder, -1);
-
-		/* TODO: This causes a memory peak at the application's startup.
-	 	*Also look at tny-camel-folder:c:2818... for more information */
-
-		tny_folder_poke_status (TNY_FOLDER (folder));
-
-		recurse_folders_async (hlrp->self, folder, tree_iter);
-
-		g_object_unref (G_OBJECT (folder));
-
-		tny_iterator_next (iter);
-	}
-
-	g_object_unref (G_OBJECT (iter));
-	g_object_unref (G_OBJECT (folders));
-
-	gtk_tree_iter_free (hlrp->parent_tree_iter);
-	g_slice_free (AsyncHelpr, hlrp);
-
-}
-
-
-static void
-recurse_folders_async (TnyGtkFolderStoreTreeModel *self, TnyFolderStore *store, GtkTreeIter *parent_tree_iter)
-{
-	AsyncHelpr *hlrp = g_slice_new0 (AsyncHelpr);
-	TnyList *folders = tny_simple_list_new ();
-
-	hlrp->self = self;
-	hlrp->parent_tree_iter = parent_tree_iter;
-
-	tny_folder_store_get_folders_async (store, folders, recurse_get_folders_callback, self->query, NULL, hlrp);
-}
-
-static void
 recurse_folders_sync (TnyGtkFolderStoreTreeModel *self, TnyFolderStore *store, GtkTreeIter *parent_tree_iter)
 {
 	TnyIterator *iter;
@@ -131,73 +56,145 @@
 
 	while (!tny_iterator_is_done (iter))
 	{
+		GtkTreeModel *mmodel = (GtkTreeModel *) self;
 		GtkTreeStore *model = GTK_TREE_STORE (self);
 		GObject *instance = G_OBJECT (tny_iterator_get_current (iter));
 		GtkTreeIter tree_iter;
-
-		gtk_tree_store_append (model, &tree_iter, parent_tree_iter);
-
 		TnyFolder *folder = NULL;
 		TnyFolderStore *folder_store = NULL;
-		
+		GtkTreeIter miter;
+		gboolean found = FALSE;
+		GObject *mark_for_removal = NULL;
+
 		if (TNY_IS_FOLDER (instance))
 			folder = TNY_FOLDER (instance);
-		
+
 		if (TNY_IS_FOLDER_STORE (folder))
 			folder_store =  TNY_FOLDER_STORE (instance);
+
+		/* We check whether we have this folder already in the tree, or 
+		 * whether it's a brand new one. If it's a new one, we'll add
+		 * it, of course */
+
+		if (gtk_tree_model_iter_children (mmodel, &miter, parent_tree_iter))
+		  do
+		  {
+			GObject *citem = NULL;
+			TnyIterator *niter = NULL;
 			
-		if (folder)
-		{
-			tny_folder_add_observer (folder, TNY_FOLDER_OBSERVER (self));
-			me->folder_observables = g_list_prepend (me->folder_observables, folder);
-		}
+			gtk_tree_model_get (mmodel, &miter, 
+				TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, 
+				&citem, -1);
 
-		if (folder_store)
-		{
-			tny_folder_store_add_observer (folder_store, TNY_FOLDER_STORE_OBSERVER (self));
-			me->store_observables = g_list_prepend (me->store_observables, folder);
-		}
+			if (citem == instance)
+			{
+				found = TRUE;
+				break;
+			}
+			if (citem)
+				g_object_unref (citem);
 
+			/* We search whether this folder that we have in the 
+			 * model, still exists in the actual list. Because if
+			 * not, it probably got removed remotely (and we need
+			 * to get rid of it in the model now) */
 
-		/* This adds a reference count to folder too. When it gets removed, that
-		   reference count is decreased automatically by the gtktreestore infra-
-		   structure. */
-		if (folder)
+			niter = tny_list_create_iterator (folders);
+			while (!tny_iterator_is_done (niter))
+			{
+				TnyFolder *ifound = TNY_FOLDER (tny_iterator_get_current (niter));
+				if (citem == (GObject *) ifound)
+					mark_for_removal = g_object_ref (ifound);
+				g_object_unref (ifound);
+				tny_iterator_next (niter);
+			}
+			g_object_unref (niter);
+
+		  } while (gtk_tree_model_iter_next (mmodel, &miter));
+
+		/* It was not found, so let's start adding it to the model! */
+
+		if (!found)
 		{
-			TnyFolder *folder = TNY_FOLDER (instance);
-			
-			gtk_tree_store_set (model, &tree_iter,
-				TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN, 
-				tny_folder_get_name (TNY_FOLDER (folder)),
-				TNY_GTK_FOLDER_STORE_TREE_MODEL_UNREAD_COLUMN, 
-				tny_folder_get_unread_count (TNY_FOLDER (folder)),
-				TNY_GTK_FOLDER_STORE_TREE_MODEL_ALL_COLUMN, 
-				tny_folder_get_all_count (TNY_FOLDER (folder)),
-				TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN,
-				tny_folder_get_folder_type (TNY_FOLDER (folder)),
-				TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN,
-				folder, -1);
-		}
+			gtk_tree_store_append (model, &tree_iter, parent_tree_iter);
 
-		if (folder_store)
-			recurse_folders_sync (self, folder_store, &tree_iter);
+			/* Making self both a folder-store as a folder observer
+			 * of this folder. This way we'll get notified when 
+			 * both a removal and a creation happens. Also when a 
+			 * rename happens: that's a removal and a creation. */
 
+			if (folder)
+			{
+				tny_folder_add_observer (folder, TNY_FOLDER_OBSERVER (self));
+				me->folder_observables = g_list_prepend (me->folder_observables, folder);
+			}
 
-		/* TODO: This causes a memory peak at the application's startup.
-	 	*Also look at tny-camel-folder:c:2818... for more information */
+			if (folder_store)
+			{
+				tny_folder_store_add_observer (folder_store, TNY_FOLDER_STORE_OBSERVER (self));
+				me->store_observables = g_list_prepend (me->store_observables, folder);
+			}
 
-		if (folder)
-			tny_folder_poke_status (TNY_FOLDER (folder));
 
-		g_object_unref (G_OBJECT (instance));
+			/* This adds a reference count to folder too. When it gets removed, that
+			   reference count is decreased automatically by the gtktreestore infra-
+			   structure. */
 
+			if (folder)
+			{
+				TnyFolder *folder = TNY_FOLDER (instance);
+				
+				gtk_tree_store_set (model, &tree_iter,
+					TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN, 
+					tny_folder_get_name (TNY_FOLDER (folder)),
+					TNY_GTK_FOLDER_STORE_TREE_MODEL_UNREAD_COLUMN, 
+					tny_folder_get_unread_count (TNY_FOLDER (folder)),
+					TNY_GTK_FOLDER_STORE_TREE_MODEL_ALL_COLUMN, 
+					tny_folder_get_all_count (TNY_FOLDER (folder)),
+					TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN,
+					tny_folder_get_folder_type (TNY_FOLDER (folder)),
+					TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN,
+					folder, -1);
+			}
+
+			/* it's a store by itself, so keep on recursing */
+			if (folder_store)
+				recurse_folders_sync (self, folder_store, &tree_iter);
+
+			/* We're a folder, we'll request a status, since we've
+			 * set self to be a folder observers of folder, we'll 
+			 * receive the status update. This makes it possible to
+			 * instantly get the unread and total counts, of course.
+			 * 
+			 * Note that the initial value is read from the cache in
+			 * case the account is set offline, in TnyCamelFolder. 
+			 * In case the account is online a STAT for POP or a 
+			 * STATUS for IMAP is asked during the poke-status impl.
+			 *
+			 * This means that no priv->folder must be loaded, no
+			 * memory peak will happen, few data must be transmitted
+			 * in case we're online. Which is perfect! */
+
+			if (folder)
+				tny_folder_poke_status (TNY_FOLDER (folder));
+		} else {
+			if (mark_for_removal)
+			{
+				printf ("We need to remove %s\n", 
+					tny_folder_get_id (TNY_FOLDER (mark_for_removal)));
+			}
+		}
+
+		g_object_unref (instance);
+
 		tny_iterator_next (iter);
 	}
 
-	g_object_unref (G_OBJECT (iter));
-	g_object_unref (G_OBJECT (folders));
+	g_object_unref (iter);
+	g_object_unref (folders);
 }
 
+
 static const gchar*
 get_root_name (TnyFolderStore *folder_store)
 {
@@ -209,6 +206,94 @@
 	return root_name;
 }
 
+
+static void 
+tny_gtk_folder_store_tree_model_on_constatus_changed (TnyAccount *account, TnyConnectionStatus status, TnyGtkFolderStoreTreeModel *self)
+{
+	GtkTreeModel *model = GTK_TREE_MODEL (self);
+	GtkTreeIter iter;
+	GtkTreeIter name_iter;
+	gboolean found = FALSE;
+
+	/* This callback handler deals with connection status changes. In case
+	 * we got connected, we can expect that, at least sometimes, new folders
+	 * might have arrived. We'll need to scan for those, so we'll recursively
+	 * start asking the account about its folders. */
+
+	if (status != TNY_CONNECTION_STATUS_CONNECTED)
+		return;
+
+	/* Note that the very first time, this core will pull all folder info.
+	 * Note that when it runs, you'll see LIST commands happen on the IMAP
+	 * socket. Especially the first time. You'll also see STATUS commands 
+	 * happen. This is, indeed, normal behaviour when this component is used.*/
+
+	/* But first, let's find-back that damn account so that we have the
+	 * actual iter behind it in the model. */
+
+	if (gtk_tree_model_get_iter_first (model, &iter))
+	  do 
+	  {
+		GObject *citem;
+
+		gtk_tree_model_get (model, &iter, 
+			TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, 
+			&citem, -1);
+		if (citem == (GObject *) account)
+		{
+			name_iter = iter;
+			found = TRUE;
+			break;
+		}
+		g_object_unref (G_OBJECT (citem));
+
+	  } while (gtk_tree_model_iter_next (model, &iter));
+
+	/* We found it, so we'll now just recursively start asking for all its
+	 * folders and subfolders. The recurse_folders_sync can indeed cope with
+	 * folders that already exist (it wont add them a second time). */
+
+	if (found)
+		recurse_folders_sync (self, TNY_FOLDER_STORE (account), &name_iter);
+}
+
+typedef struct
+{
+	TnyGtkFolderStoreTreeModel *self;
+	TnyAccount *account;
+} AccNotYetReadyInfo;
+
+static gboolean
+account_was_not_yet_ready_idle (gpointer user_data)
+{
+	AccNotYetReadyInfo *info = (AccNotYetReadyInfo *) user_data;
+	gboolean repeat = TRUE;
+
+	if (tny_account_is_ready (info->account))
+	{
+		g_signal_connect (info->account, "connection-status-changed",
+			G_CALLBACK (tny_gtk_folder_store_tree_model_on_constatus_changed), info->self);
+
+		tny_gtk_folder_store_tree_model_on_constatus_changed (info->account, 
+			tny_account_get_connection_status (info->account), info->self);
+
+		repeat = FALSE;
+	}
+
+	return repeat;
+}
+
+static void 
+account_was_not_yet_ready_destroy (gpointer user_data)
+{
+	AccNotYetReadyInfo *info = (AccNotYetReadyInfo *) user_data;
+
+	g_object_unref (info->account);
+	g_object_unref (info->self);
+
+	g_slice_free (AccNotYetReadyInfo, user_data);
+}
+
 static void
 tny_gtk_folder_store_tree_model_add_i (TnyGtkFolderStoreTreeModel *self, TnyFolderStore *folder_store, treeaddfunc func, const gchar *root_name)
 {
@@ -226,54 +311,44 @@
 		TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN,
 		folder_store, -1);
 
-	recurse_folders_sync (self, TNY_FOLDER_STORE (folder_store), &name_iter);
+	/* In case we added a store account, it's possible that the account 
+	 * will have "the account just got connected" events happening. Accounts
+	 * that just got connected might have new folders for us to know about.
+	 * That's why we'll handle connection changes. */
 
-	/* Add an observer for the root folder store */
-	tny_folder_store_add_observer (folder_store, TNY_FOLDER_STORE_OBSERVER (self));
-	self->store_observables = g_list_prepend (self->store_observables, folder_store);
+	if (TNY_IS_STORE_ACCOUNT (folder_store)) {
+		if (!tny_account_is_ready (TNY_ACCOUNT (folder_store))) 
+		{
+			AccNotYetReadyInfo *info = g_slice_new (AccNotYetReadyInfo);
 
-	g_object_unref (G_OBJECT (folders));
+			info->account = TNY_ACCOUNT (g_object_ref (folder_store));
+			info->self = TNY_GTK_FOLDER_STORE_TREE_MODEL (g_object_ref (self));
 
-	return;
-}
+			g_timeout_add_full (G_PRIORITY_HIGH, 100, 
+				account_was_not_yet_ready_idle, 
+				info, account_was_not_yet_ready_destroy);
 
-static void
-tny_gtk_folder_store_tree_model_add_async_i (TnyGtkFolderStoreTreeModel *self, TnyFolderStore *folder_store, treeaddfunc func, const gchar *root_name)
-{
-	GtkTreeStore *model = GTK_TREE_STORE (self);
-	GtkTreeIter first, *name_iter;
-	gboolean need_add = TRUE;
-
-	if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (self), &first))
-	{
-		func (model, &first, NULL);
-		need_add = FALSE;
+		} else
+			g_signal_connect (folder_store, "connection-status-changed",
+				G_CALLBACK (tny_gtk_folder_store_tree_model_on_constatus_changed), self);
 	}
 
-	name_iter = gtk_tree_iter_copy (&first);
+	recurse_folders_sync (self, TNY_FOLDER_STORE (folder_store), &name_iter);
 
-	if (need_add)
-		func (model, name_iter, NULL);
+	/* Add an observer for the root folder store, so that we can observe 
+	 * the actual account too. */
 
-	/* This adds a reference count to folder_store too. When it gets removed,
-	   that reference count is decreased automatically by the gtktreestore
-	   infrastructure. */
+	tny_folder_store_add_observer (folder_store, TNY_FOLDER_STORE_OBSERVER (self));
+	self->store_observables = g_list_prepend (self->store_observables, folder_store);
 
-	gtk_tree_store_set (model, name_iter,
-		TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN, root_name,
-		TNY_GTK_FOLDER_STORE_TREE_MODEL_UNREAD_COLUMN, 0,
-		TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN, TNY_FOLDER_TYPE_ROOT,
-		TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN,
-		folder_store, -1);
+	g_object_unref (G_OBJECT (folders));
 
-	recurse_folders_async (self, TNY_FOLDER_STORE (folder_store), name_iter);
-
 	return;
 }
 
+
 /**
  * tny_gtk_folder_store_tree_model_new:
- * @async: Whether or not this component should attempt to asynchronously fill the tree
  * @query: the #TnyFolderStoreQuery that will be used to retrieve the folders of each folder_store
  *
  * Create a new #GtkTreeModel instance suitable for showing  
@@ -283,11 +358,13 @@
  * #TnyFolderStore instances
  **/
 GtkTreeModel*
-tny_gtk_folder_store_tree_model_new (gboolean async, TnyFolderStoreQuery *query)
+tny_gtk_folder_store_tree_model_new (TnyFolderStoreQuery *query)
 {
 	TnyGtkFolderStoreTreeModel *self = g_object_new (TNY_TYPE_GTK_FOLDER_STORE_TREE_MODEL, NULL);
-	self->is_async = FALSE;
-	if (query) self->query = g_object_ref (G_OBJECT (query));
+
+	if (query) 
+		self->query = g_object_ref (G_OBJECT (query));
+
 	return GTK_TREE_MODEL (self);
 }
 
@@ -342,7 +419,7 @@
 	me->iterator_lock = NULL;
 
 	if (me->query)
-		g_object_unref (G_OBJECT (me->query));
+		g_object_unref (me->query);
 
 	(*parent_class->finalize) (object);
 }
@@ -406,15 +483,11 @@
 	g_mutex_lock (me->iterator_lock);
 
 	/* Prepend something to the list */
-	g_object_ref (G_OBJECT (item));
+	g_object_ref (item);
 	me->first = g_list_prepend (me->first, item);
 
-	if (me->is_async)
-		tny_gtk_folder_store_tree_model_add_async_i (me, TNY_FOLDER_STORE (item), 
-			gtk_tree_store_prepend, root_name);
-	else
-		tny_gtk_folder_store_tree_model_add_i (me, TNY_FOLDER_STORE (item), 
-			gtk_tree_store_prepend, root_name);
+	tny_gtk_folder_store_tree_model_add_i (me, TNY_FOLDER_STORE (item), 
+		gtk_tree_store_prepend, root_name);
 
 	g_mutex_unlock (me->iterator_lock);
 }
@@ -428,16 +501,12 @@
 	g_mutex_lock (me->iterator_lock);
 
 	/* Prepend something to the list */
-	g_object_ref (G_OBJECT (item));
+	g_object_ref (item);
 	me->first = g_list_prepend (me->first, item);
 
-	if (me->is_async)
-		tny_gtk_folder_store_tree_model_add_async_i (me, TNY_FOLDER_STORE (item), 
-			gtk_tree_store_prepend, get_root_name (TNY_FOLDER_STORE (item)));
-	else
-		tny_gtk_folder_store_tree_model_add_i (me, TNY_FOLDER_STORE (item), 
-			gtk_tree_store_prepend, get_root_name (TNY_FOLDER_STORE (item)));
-	
+	tny_gtk_folder_store_tree_model_add_i (me, TNY_FOLDER_STORE (item), 
+		gtk_tree_store_prepend, get_root_name (TNY_FOLDER_STORE (item)));
+
 	g_mutex_unlock (me->iterator_lock);
 }
 
@@ -457,15 +526,11 @@
 	g_mutex_lock (me->iterator_lock);
 
 	/* Append something to the list */
-	g_object_ref (G_OBJECT (item));
+	g_object_ref (item);
 	me->first = g_list_append (me->first, item);
 
-	if (me->is_async)
-		tny_gtk_folder_store_tree_model_add_async_i (me, TNY_FOLDER_STORE (item), 
-			gtk_tree_store_append, root_name);
-	else
-		tny_gtk_folder_store_tree_model_add_i (me, TNY_FOLDER_STORE (item), 
-			gtk_tree_store_append, root_name);
+	tny_gtk_folder_store_tree_model_add_i (me, TNY_FOLDER_STORE (item), 
+		gtk_tree_store_append, root_name);
 
 	g_mutex_unlock (me->iterator_lock);
 }
@@ -478,15 +543,11 @@
 	g_mutex_lock (me->iterator_lock);
 
 	/* Append something to the list */
-	g_object_ref (G_OBJECT (item));
+	g_object_ref (item);
 	me->first = g_list_append (me->first, item);
 
-	if (me->is_async)
-		tny_gtk_folder_store_tree_model_add_async_i (me, TNY_FOLDER_STORE (item), 
-			gtk_tree_store_append, get_root_name (TNY_FOLDER_STORE (item)));
-	else
-		tny_gtk_folder_store_tree_model_add_i (me, TNY_FOLDER_STORE (item), 
-			gtk_tree_store_append, get_root_name (TNY_FOLDER_STORE (item)));
+	tny_gtk_folder_store_tree_model_add_i (me, TNY_FOLDER_STORE (item), 
+		gtk_tree_store_append, get_root_name (TNY_FOLDER_STORE (item)));
 
 	g_mutex_unlock (me->iterator_lock);
 }
@@ -526,14 +587,12 @@
 	   actually really part of the list. */
 
 	if (gtk_tree_model_get_iter_first (model, &iter))
-	  while (gtk_tree_model_iter_next (model, &iter))
+	  do 
 	  {
-		GObject *citem;
-
+		GObject *citem = NULL;
 		gtk_tree_model_get (model, &iter, 
 			TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, 
 			&citem, -1);
-
 		if (citem == item)
 		{
 			/* This removes a reference count */
@@ -541,9 +600,11 @@
 			g_object_unref (G_OBJECT (item));
 			break;
 		}
-		g_object_unref (G_OBJECT (citem));
-	  }
+		if (citem)
+			g_object_unref (G_OBJECT (citem));
 
+	  } while (gtk_tree_model_iter_next (model, &iter));
+
 	g_mutex_unlock (me->iterator_lock);
 }
 
@@ -593,6 +654,10 @@
 	TnyFolder *changed_folder = tny_folder_change_get_folder (change);
 	TnyFolderChangeChanged changed = tny_folder_change_get_changed (change);
 
+	/* This updater will get the folder out of the model, compare with 
+	 * the changed_folder pointer, and if there's a match it will update
+	 * the values of the model with the values from the folder. */
+
 	gtk_tree_model_get (model, iter, 
 		TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN, 
 		&type, -1);
@@ -628,14 +693,13 @@
 				TNY_GTK_FOLDER_STORE_TREE_MODEL_UNREAD_COLUMN, 
 				unread,
 				TNY_GTK_FOLDER_STORE_TREE_MODEL_ALL_COLUMN, 
-				total,
-				-1);
+				total, -1);
 		}
 
-		g_object_unref (G_OBJECT (folder));
+		g_object_unref (folder);
 	}
 
-	g_object_unref (G_OBJECT (changed_folder));
+	g_object_unref (changed_folder);
 
 	return FALSE;
 }
@@ -648,13 +712,17 @@
 	TnyFolderType type = TNY_FOLDER_TYPE_UNKNOWN;
 	GObject *folder = user_data1;
 
+	/* The deleter will compare all folders in the model with the deleted 
+	 * folder @folder, and if there's a match it will delete the folder's
+	 * row from the model. */
+
 	gtk_tree_model_get (model, iter, 
 		TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN, 
 		&type, -1);
 
 	if (type != TNY_FOLDER_TYPE_ROOT) 
 	{
-		GObject *fol;
+		GObject *fol = NULL;
 
 		gtk_tree_model_get (model, iter, 
 			TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, 
@@ -665,7 +733,8 @@
 			retval = TRUE;
 		}
 
-		g_object_unref (G_OBJECT (fol));
+		if (fol)
+			g_object_unref (fol);
 	}
 
 	return retval;
@@ -675,6 +744,8 @@
 static gboolean
 find_store_iter (GtkTreeModel *model, GtkTreeIter *iter, GtkTreeIter *f, gpointer user_data)
 {
+	/* Finding the iter for a given folder */
+
 	do
 	{
 		GtkTreeIter child;
@@ -687,14 +758,14 @@
 			&type, -1);
 
 		gtk_tree_model_get (model, iter, 
-				    TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, 
-				    &fol, -1);
+			TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, 
+			&fol, -1);
 		
 		if (fol == user_data)
 			found = TRUE;
 		
-		if (fol != NULL)
-			g_object_unref (G_OBJECT (fol));
+		if (fol)
+			g_object_unref (fol);
 
 		if (found) {
 			*f = *iter;
@@ -798,7 +869,8 @@
 				GtkTreeIter newiter;
 				TnyFolder *folder = TNY_FOLDER (tny_iterator_get_current (miter));
 
-				/* See early added below! 
+				/* See early added below! (#CCUX)
+
 				tny_folder_add_observer (TNY_FOLDER (folder), TNY_FOLDER_OBSERVER (self));
 				tny_folder_store_add_observer (TNY_FOLDER_STORE (folder), TNY_FOLDER_STORE_OBSERVER (self));*/
 
@@ -823,11 +895,11 @@
 					TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN,
 					folder, -1);
 
-				g_object_unref (G_OBJECT (folder));
+				g_object_unref (folder);
 				tny_iterator_next (miter);
 			}
-			g_object_unref (G_OBJECT (miter));
-			g_object_unref (G_OBJECT (created));
+			g_object_unref (miter);
+			g_object_unref (created);
 		}
 		g_object_unref (G_OBJECT (parentstore));
 	}
@@ -844,11 +916,11 @@
 		{
 			TnyFolder *folder = TNY_FOLDER (tny_iterator_get_current (miter));
 			gtk_tree_model_foreach (model, deleter, folder);
-			g_object_unref (G_OBJECT (folder));
+			g_object_unref (folder);
 			tny_iterator_next (miter);
 		}
-		g_object_unref (G_OBJECT (miter));
-		g_object_unref (G_OBJECT (removed));
+		g_object_unref (miter);
+		g_object_unref (removed);
 	}
 
 
@@ -888,7 +960,7 @@
 		{
 			TnyFolder *folder = TNY_FOLDER (tny_iterator_get_current (miter));
 
-			/* Already added! 
+			/* Already added! (#CCUX)
 			 * We can't add these in the idle because the thread might
 			 * be added subfolders right now! (the idle would register
 			 * self as an observer too late!) 
@@ -899,11 +971,11 @@
 			tny_folder_add_observer (TNY_FOLDER (folder), TNY_FOLDER_OBSERVER (self));
 			tny_folder_store_add_observer (TNY_FOLDER_STORE (folder), TNY_FOLDER_STORE_OBSERVER (self));
 
-			g_object_unref (G_OBJECT (folder));
+			g_object_unref (folder);
 			tny_iterator_next (miter);
 		}
-		g_object_unref (G_OBJECT (miter));
-		g_object_unref (G_OBJECT (created));
+		g_object_unref (miter);
+		g_object_unref (created);
 	}
 
 	g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
Index: tests/c-demo/tny-demoui-summary-view.c
===================================================================
--- tests/c-demo/tny-demoui-summary-view.c	(revision 2535)
+++ tests/c-demo/tny-demoui-summary-view.c	(working copy)
@@ -93,7 +93,6 @@
  	GtkComboBox *account_view;
 	GtkTreeView *mailbox_view, *header_view;
 	TnyMsgView *msg_view;
-	guint accounts_reloaded_signal;
 	GtkWidget *status, *progress, *online_button, *poke_button, *sync_button;
 	guint status_id;
 	gulong mailbox_select_sid;
@@ -276,7 +275,7 @@
 }
 
 static void 
-reload_accounts_first (TnySummaryView *self, gboolean first_time)
+load_accounts (TnySummaryView *self, gboolean first_time)
 {
 	TnyDemouiSummaryViewPriv *priv = TNY_DEMOUI_SUMMARY_VIEW_GET_PRIVATE (self);
 	TnyAccountStore *account_store = priv->account_store;
@@ -290,11 +289,7 @@
 
 	/* TnyGtkFolderStoreTreeModel is also a TnyList (it simply implements both the
 	   TnyList and the GtkTreeModel interfaces) */
-#if PLATFORM==1
-	mailbox_model = tny_gtk_folder_store_tree_model_new (TRUE, NULL);
-#else
-	mailbox_model = tny_gtk_folder_store_tree_model_new (FALSE, NULL);
-#endif
+	mailbox_model = tny_gtk_folder_store_tree_model_new (NULL);
 
 	g_object_unref (G_OBJECT (query));
 
@@ -370,19 +365,7 @@
 	return;
 }
 
-static void 
-reload_accounts (TnySummaryView *self)
-{
-	reload_accounts_first (self, FALSE);
-}
 
-static void
-accounts_reloaded (TnyAccountStore *store, gpointer user_data)
-{
-	reload_accounts ((TnySummaryView *)user_data);
-	return;
-}
-
 static void 
 online_button_toggled (GtkToggleButton *togglebutton, gpointer user_data)
 {
@@ -494,16 +477,11 @@
 		TnyDevice *odevice = tny_account_store_get_device (priv->account_store);
 
 		if (g_signal_handler_is_connected (G_OBJECT (odevice), priv->connchanged_signal))
-		{
 			g_signal_handler_disconnect (G_OBJECT (odevice), 
 				priv->connchanged_signal);
-		}
 
-		g_signal_handler_disconnect (G_OBJECT (priv->account_store),
-			priv->accounts_reloaded_signal);
-
-		g_object_unref (G_OBJECT (priv->account_store));
-		g_object_unref (G_OBJECT (odevice));
+		g_object_unref (priv->account_store);
+		g_object_unref (odevice);
 	}
 
 	g_object_ref (G_OBJECT (account_store));
@@ -514,12 +492,8 @@
 
 	priv->account_store = account_store;
 
-	priv->accounts_reloaded_signal = g_signal_connect (
-		G_OBJECT (account_store), "accounts_reloaded",
-		G_CALLBACK (accounts_reloaded), self);
+	load_accounts ((TnySummaryView *) self, TRUE);
 
-	reload_accounts_first ((TnySummaryView *) self, TRUE);
-
 	g_object_unref (G_OBJECT (device));
 
 	return;
@@ -1935,16 +1909,11 @@
 	TnyDemouiSummaryViewPriv *priv = TNY_DEMOUI_SUMMARY_VIEW_GET_PRIVATE (self);
 
 	if (priv->current_accounts)
-		g_object_unref (G_OBJECT (priv->current_accounts));
+		g_object_unref (priv->current_accounts);
 
-	if (G_LIKELY (priv->account_store))
-	{
-		g_signal_handler_disconnect (G_OBJECT (priv->account_store),
-			priv->accounts_reloaded_signal);
+	if (priv->account_store)
+		g_object_unref (priv->account_store);
 
-		g_object_unref (G_OBJECT (priv->account_store));
-	}
-
 	g_mutex_lock (priv->monitor_lock);
 	if (priv->monitor)
 	{
Index: libtinymail-maemo/tny-maemo-account-store.h
===================================================================
--- libtinymail-maemo/tny-maemo-account-store.h	(revision 2535)
+++ libtinymail-maemo/tny-maemo-account-store.h	(working copy)
@@ -53,9 +53,6 @@
 TnyAccountStore* tny_maemo_account_store_new (void);
 TnySessionCamel* tny_maemo_account_store_get_session (TnyMaemoAccountStore *self);
 
-void tny_maemo_account_store_add_store_account (TnyMaemoAccountStore *self, TnyStoreAccount *account);
-void tny_maemo_account_store_add_transport_account (TnyAccountStore *self, TnyTransportAccount *account);
-
 G_END_DECLS
 
 #endif
Index: libtinymail-maemo/tny-maemo-account-store.c
===================================================================
--- libtinymail-maemo/tny-maemo-account-store.c	(revision 2535)
+++ libtinymail-maemo/tny-maemo-account-store.c	(working copy)
@@ -157,11 +157,7 @@
 	gchar *ptr = strrchr (key, '/'); ptr++;
 
 	if (!strcmp (ptr, "count"))
-	{
 		kill_stored_accounts (priv);
-		g_signal_emit (self, 
-			tny_account_store_signals [TNY_ACCOUNT_STORE_ACCOUNTS_RELOADED], 0);
-	}
 
 	g_free (key);
 
@@ -498,30 +494,6 @@
 
 
 
-void
-tny_maemo_account_store_add_store_account (TnyMaemoAccountStore *self, TnyStoreAccount *account)
-{
-	tny_maemo_account_store_notify_remove (TNY_ACCOUNT_STORE (self));
-	tny_maemo_account_store_add_account (TNY_ACCOUNT_STORE (self), TNY_ACCOUNT (account), "store");
-	tny_maemo_account_store_notify_add (TNY_ACCOUNT_STORE (self));
-
-	g_signal_emit (self, tny_account_store_signals [TNY_ACCOUNT_STORE_ACCOUNT_INSERTED], 0, account);
-
-	return;
-}
-
-void
-tny_maemo_account_store_add_transport_account (TnyAccountStore *self, TnyTransportAccount *account)
-{
-	tny_maemo_account_store_notify_remove (TNY_ACCOUNT_STORE (self));
-	tny_maemo_account_store_add_account (TNY_ACCOUNT_STORE (self), TNY_ACCOUNT (account), "transport");
-	tny_maemo_account_store_notify_add (TNY_ACCOUNT_STORE (self));
-
-	g_signal_emit (self, tny_account_store_signals [TNY_ACCOUNT_STORE_ACCOUNT_INSERTED], 0, account);
-
-	return;
-}
-
 static TnyDevice*
 tny_maemo_account_store_get_device (TnyAccountStore *self)
 {
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 2535)
+++ ChangeLog	(working copy)
@@ -1,3 +1,16 @@
+2007-07-31  Philip Van Hoof  <pvanhoof gnome org>
+
+	* Merging back devel/pvanhoof/sessionwork to trunk/
+
+2007-07-31  Philip Van Hoof  <pvanhoof gnome org>
+
+	* Cleaning up, coding style fixes
+	* Review of TnyCamelFolder and TnyCamelStoreAccount
+
+2007-07-30  Philip Van Hoof  <pvanhoof gnome org>
+
+	* Various fixes that make Modest actually work with this
+
 2007-07-30  Javier Fernandez Garcia-Boente  <jfernandez igalia com>
 
 	* Fixed some bugs in TnyMergeFolder notification function. This
@@ -23,6 +36,47 @@
 
 	* Merging the Cond patch from devel/sessionwork
 
+2007-07-29  Philip Van Hoof  <pvanhoof gnome org>
+
+	* The long awaited alert, get_pass and forget_pass now in the mainloop
+
+	* This was a major API and behaviour change
+
+2007-07-29  Philip Van Hoof  <pvanhoof gnome org>
+
+	* Fixed a race condition when the account was or is connection or not
+	yet finished connecting while the connection-status-changed signal was
+	already being used. Introduced a new API for this
+	* Introduced the tny_account_is_ready API, which indicates when an
+	account is not only valid as instance, but also fully registered
+	within the system.
+	* Implemented some missing implementations in TnyCombinedAccount
+
+	* This was a major API change
+
+2007-07-27  Philip Van Hoof  <pvanhoof gnome org>
+
+	* Dealing with remotely removed folders
+	* The poke status calls are now on the same queue as the other
+	operations
+	* Rewritten the TnySessionCamel infrastructure that connects accounts
+	and sets them up
+	* Added support for detecting folder changes to
+	TnyGtkFolderStoreTreeModel
+	* API change on tny_camel_account_set_online. The last argument is now
+	a callback rather than a GError. In the callback you can know about
+	when the account got connected and if not, why it failed
+
+	* Cond locks in the queues of the store accounts while the callbacks
+	are happening. This is a significant policy change in locking
+	behaviour that should be well tested. 
+
+	* This was a major API change in TnyAccount
+
+2007-07-27  Philip Van Hoof  <pvanhoof gnome org>
+
+	* Branchpoint "devel/sessionwork"
+
 2007-07-26  Philip Van Hoof  <pvanhoof gnome org>
 
 	* More granularity in the locking of the POP code
Index: libtinymail-gnome-desktop/tny-gnome-account-store.c
===================================================================
--- libtinymail-gnome-desktop/tny-gnome-account-store.c	(revision 2535)
+++ libtinymail-gnome-desktop/tny-gnome-account-store.c	(working copy)
@@ -153,13 +153,8 @@
 	gchar *key = g_strdup (entry->key);
 	gchar *ptr = strrchr (key, '/'); ptr++;
 
-
 	if (!strcmp (ptr, "count"))
-	{
 		kill_stored_accounts (priv);
-		g_signal_emit (self, 
-			tny_account_store_signals [TNY_ACCOUNT_STORE_ACCOUNTS_RELOADED], 0);
-	}
 
 	g_free (key);
 
@@ -489,44 +484,7 @@
 	return;
 }
 
-/**
- * tny_gnome_account_store_add_store_account:
- * @self: a #TnyGnomeAccountStore instance
- * @account: a #TnyStoreAccount instance to add
- * 
- * Add @account to @self
- **/
-void
-tny_gnome_account_store_add_store_account (TnyGnomeAccountStore *self, TnyStoreAccount *account)
-{
-	tny_gnome_account_store_notify_remove (TNY_ACCOUNT_STORE (self));
-	tny_gnome_account_store_add_account (TNY_ACCOUNT_STORE (self), TNY_ACCOUNT (account), "store");
-	tny_gnome_account_store_notify_add (TNY_ACCOUNT_STORE (self));
 
-	g_signal_emit (self, tny_account_store_signals [TNY_ACCOUNT_STORE_ACCOUNT_INSERTED], 0, account);
-
-	return;
-}
-
-/**
- * tny_gnome_account_store_add_transport_account:
- * @self: a #TnyGnomeAccountStore instance
- * @account: a #TnyTransportAccount instance to add
- * 
- * Add @account to @self
- **/
-void
-tny_gnome_account_store_add_transport_account (TnyGnomeAccountStore *self, TnyTransportAccount *account)
-{
-	tny_gnome_account_store_notify_remove (TNY_ACCOUNT_STORE (self));
-	tny_gnome_account_store_add_account (TNY_ACCOUNT_STORE (self), TNY_ACCOUNT (account), "transport");
-	tny_gnome_account_store_notify_add (TNY_ACCOUNT_STORE (self));
-
-	g_signal_emit (self, tny_account_store_signals [TNY_ACCOUNT_STORE_ACCOUNT_INSERTED], 0, account);
-
-	return;
-}
-
 static TnyDevice*
 tny_gnome_account_store_get_device (TnyAccountStore *self)
 {
Index: libtinymail-gnome-desktop/tny-gnome-account-store.h
===================================================================
--- libtinymail-gnome-desktop/tny-gnome-account-store.h	(revision 2535)
+++ libtinymail-gnome-desktop/tny-gnome-account-store.h	(working copy)
@@ -52,8 +52,6 @@
 TnyAccountStore* tny_gnome_account_store_new (void);
 TnySessionCamel* tny_gnome_account_store_get_session (TnyGnomeAccountStore *self);
 
-void tny_gnome_account_store_add_store_account (TnyGnomeAccountStore *self, TnyStoreAccount *account);
-void tny_gnome_account_store_add_transport_account (TnyGnomeAccountStore *self, TnyTransportAccount *account);
 
 G_END_DECLS
 
Index: libtinymail-olpc/tny-olpc-account-store.h
===================================================================
--- libtinymail-olpc/tny-olpc-account-store.h	(revision 2535)
+++ libtinymail-olpc/tny-olpc-account-store.h	(working copy)
@@ -52,9 +52,6 @@
 TnyAccountStore* tny_olpc_account_store_new (void);
 TnySessionCamel* tny_olpc_account_store_get_session (TnyOlpcAccountStore *self);
 
-void tny_olpc_account_store_add_store_account (TnyOlpcAccountStore *self, TnyStoreAccount *account);
-void tny_olpc_account_store_add_transport_account (TnyOlpcAccountStore *self, TnyTransportAccount *account);
-
 G_END_DECLS
 
 #endif
Index: libtinymail/tny-account-store.c
===================================================================
--- libtinymail/tny-account-store.c	(revision 2535)
+++ libtinymail/tny-account-store.c	(working copy)
@@ -374,82 +374,6 @@
 	if (!tny_account_store_initialized) 
 	{
 /**
- * TnyAccountStore::account-changed
- * @self: the object on which the signal is emitted
- * @arg1: the #TnyAccount of the account that changed
- * @user_data: user data set when the signal handler was connected
- *
- * API WARNING: This API might change
- *
- * Emitted when an account in the store changed
- */
-		tny_account_store_signals[TNY_ACCOUNT_STORE_ACCOUNT_CHANGED] =
-		   g_signal_new ("account_changed",
-			TNY_TYPE_ACCOUNT_STORE,
-			G_SIGNAL_RUN_FIRST,
-			G_STRUCT_OFFSET (TnyAccountStoreIface, account_changed),
-			NULL, NULL,
-			g_cclosure_marshal_VOID__POINTER,
-			G_TYPE_NONE, 1, TNY_TYPE_ACCOUNT);
-
-/**
- * TnyAccountStore::account-inserted
- * @self: the object on which the signal is emitted
- * @arg1: the #TnyAccount of the account that got inserted
- * @user_data: user data set when the signal handler was connected.
- *
- * API WARNING: This API might change
- *
- * Emitted when an account is added to the store
- */
-		tny_account_store_signals[TNY_ACCOUNT_STORE_ACCOUNT_INSERTED] =
-		   g_signal_new ("account_inserted",
-			TNY_TYPE_ACCOUNT_STORE,
-			G_SIGNAL_RUN_FIRST,
-			G_STRUCT_OFFSET (TnyAccountStoreIface, account_inserted),
-			NULL, NULL,
-			g_cclosure_marshal_VOID__POINTER,
-			G_TYPE_NONE, 1, TNY_TYPE_ACCOUNT);
-
-/**
- * TnyAccountStore::account-removed
- * @self: the object on which the signal is emitted
- * @arg1: the #TnyAccount of the account that got removed
- * @user_data: user data set when the signal handler was connected.
- *
- * API WARNING: This API might change
- *
- * Emitted when an account is removed from the store
- */
-		tny_account_store_signals[TNY_ACCOUNT_STORE_ACCOUNT_REMOVED] =
-		   g_signal_new ("account_removed",
-			TNY_TYPE_ACCOUNT_STORE,
-			G_SIGNAL_RUN_FIRST,
-			G_STRUCT_OFFSET (TnyAccountStoreIface, account_removed),
-			NULL, NULL,
-			g_cclosure_marshal_VOID__POINTER,
-			G_TYPE_NONE, 1, TNY_TYPE_ACCOUNT);
-
-/**
- * TnyAccountStore::accounts-reloaded
- * @self: the object on which the signal is emitted
- *
- * API WARNING: This API might change
- *
- * Emitted when the store reloads the accounts
- */
-		tny_account_store_signals[TNY_ACCOUNT_STORE_ACCOUNTS_RELOADED] =
-		   g_signal_new ("accounts_reloaded",
-			TNY_TYPE_ACCOUNT_STORE,
-			G_SIGNAL_RUN_FIRST,
-			G_STRUCT_OFFSET (TnyAccountStoreIface, accounts_reloaded),
-			NULL, NULL,
-			g_cclosure_marshal_VOID__VOID,
-			G_TYPE_NONE, 0);
-
-
-
-/**
  * TnyAccountStore::connecting-started
  * @self: the object on which the signal is emitted
  * @user_data: user data set when the signal handler was connected.
@@ -465,23 +389,6 @@
 		g_cclosure_marshal_VOID__VOID, 
 		G_TYPE_NONE, 0);
 
-
-/**
- * TnyAccountStore::connecting-finished
- * @self: the object on which the signal is emitted
- * @user_data: user data set when the signal handler was connected.
- *
- * Emitted when the store finished trying to connect the accounts
- */
-	tny_account_store_signals[TNY_ACCOUNT_STORE_CONNECTING_FINISHED] =
-	   g_signal_new ("connecting_finished",
-		TNY_TYPE_ACCOUNT_STORE,
-		G_SIGNAL_RUN_FIRST,
-		G_STRUCT_OFFSET (TnyAccountStoreIface, connecting_finished),
-		NULL, NULL,
-		g_cclosure_marshal_VOID__VOID, 
-		G_TYPE_NONE, 0);
-
 		tny_account_store_initialized = TRUE;
 	}
 	return;
@@ -584,12 +491,7 @@
   static GType etype = 0;
   if (etype == 0) {
     static const GEnumValue values[] = {
-      { TNY_ACCOUNT_STORE_ACCOUNT_CHANGED, "TNY_ACCOUNT_STORE_ACCOUNT_CHANGED", "changed" },
-      { TNY_ACCOUNT_STORE_ACCOUNT_INSERTED, "TNY_ACCOUNT_STORE_ACCOUNT_INSERTED", "inserted" },
-      { TNY_ACCOUNT_STORE_ACCOUNT_REMOVED, "TNY_ACCOUNT_STORE_ACCOUNT_REMOVED", "removed" },
-      { TNY_ACCOUNT_STORE_ACCOUNTS_RELOADED, "TNY_ACCOUNT_STORE_ACCOUNTS_RELOADED", "reloaded" },
       { TNY_ACCOUNT_STORE_CONNECTING_STARTED, "TNY_ACCOUNT_STORE_CONNECTING_STARTED", "started" },
-      { TNY_ACCOUNT_STORE_CONNECTING_FINISHED, "TNY_ACCOUNT_STORE_CONNECTING_FINISHED", "finished" },
       { TNY_ACCOUNT_STORE_LAST_SIGNAL,  "TNY_ACCOUNT_STORE_LAST_SIGNAL", "last-signal" },
       { 0, NULL, NULL }
     };
Index: libtinymail/tny-account-store.h
===================================================================
--- libtinymail/tny-account-store.h	(revision 2535)
+++ libtinymail/tny-account-store.h	(working copy)
@@ -35,12 +35,7 @@
 
 enum _TnyAccountStoreSignal
 {
-	TNY_ACCOUNT_STORE_ACCOUNT_CHANGED,
-	TNY_ACCOUNT_STORE_ACCOUNT_INSERTED,
-	TNY_ACCOUNT_STORE_ACCOUNT_REMOVED,
-	TNY_ACCOUNT_STORE_ACCOUNTS_RELOADED,
 	TNY_ACCOUNT_STORE_CONNECTING_STARTED,
-	TNY_ACCOUNT_STORE_CONNECTING_FINISHED,
 	TNY_ACCOUNT_STORE_LAST_SIGNAL
 };
 
@@ -80,13 +75,7 @@
 	TnyAccount* (*find_account_func) (TnyAccountStore *self, const gchar *url_string);
 
 	/* Signals */
-	void (*account_changed) (TnyAccountStore *self, TnyAccount *account);
-	void (*account_inserted) (TnyAccountStore *self, TnyAccount *account);
-	void (*account_removed) (TnyAccountStore *self, TnyAccount *account);
-	void (*accounts_reloaded) (TnyAccountStore *self);
-
 	void (*connecting_started) (TnyAccountStore *self);
-	void (*connecting_finished) (TnyAccountStore *self);
 };
 
 GType tny_account_store_get_type (void);
Index: libtinymail/tny-combined-account.c
===================================================================
--- libtinymail/tny-combined-account.c	(revision 2535)
+++ libtinymail/tny-combined-account.c	(working copy)
@@ -322,7 +322,40 @@
 	tny_folder_store_remove_observer (TNY_FOLDER_STORE (priv->store_account), observer);
 }
 
+static void 
+tny_combined_account_start_operation (TnyAccount *self, TnyStatusDomain domain, TnyStatusCode code, TnyStatusCallback status_callback, gpointer status_user_data)
+{
+	TnyCombinedAccountPriv *priv = TNY_COMBINED_ACCOUNT_GET_PRIVATE (self);
 
+	tny_account_start_operation (TNY_ACCOUNT (priv->store_account), domain, code, status_callback, status_user_data);
+
+	return;
+}
+
+static void 
+tny_combined_account_stop_operation (TnyAccount *self, gboolean *canceled)
+{
+	TnyCombinedAccountPriv *priv = TNY_COMBINED_ACCOUNT_GET_PRIVATE (self);
+
+	tny_account_stop_operation (TNY_ACCOUNT (priv->store_account), canceled);
+
+	return;
+}
+
+static gboolean 
+tny_combined_account_is_ready (TnyAccount *self)
+{
+	TnyCombinedAccountPriv *priv = TNY_COMBINED_ACCOUNT_GET_PRIVATE (self);
+	gboolean retval = FALSE;
+
+	if (tny_account_is_ready (TNY_ACCOUNT (priv->store_account)) &&
+	    tny_account_is_ready (TNY_ACCOUNT (priv->transport_account))) {
+		retval = TRUE;
+	}
+	return retval;
+}
+
+
 static void
 on_subscription_changed_signal (TnyStoreAccount *sa, TnyFolder *folder, gpointer user_data)
 {
@@ -473,6 +506,9 @@
 	klass->get_account_type_func = tny_combined_account_get_account_type;
 	klass->cancel_func = tny_combined_account_cancel;
 	klass->matches_url_string_func = tny_combined_account_matches_url_string;
+	klass->start_operation_func = tny_combined_account_start_operation;
+	klass->stop_operation_func = tny_combined_account_stop_operation;
+	klass->is_ready_func = tny_combined_account_is_ready;
 }
 
 
Index: libtinymail/tny-account.c
===================================================================
--- libtinymail/tny-account.c	(revision 2535)
+++ libtinymail/tny-account.c	(working copy)
@@ -32,6 +32,35 @@
 
 
 /**
+ * tny_account_is_ready:
+ * @self: a #TnyAccount object
+ *
+ * Some implementations of #TnyAccount need registration in a subsystem or 
+ * factory before they are not only valid instances, but also ready to use. For
+ * example before their connection-status-changed signal emissions are accurate.
+ * This boolean property will tell you if @self is ready for that.
+ *
+ * Return value: whether @self is ready for use
+ **/
+gboolean 
+tny_account_is_ready (TnyAccount *self)
+{
+	gboolean retval = FALSE;
+
+#ifdef DBC /* require */
+	g_assert (TNY_IS_ACCOUNT (self));
+	g_assert (TNY_ACCOUNT_GET_IFACE (self)->is_ready_func != NULL);
+#endif
+
+	retval = TNY_ACCOUNT_GET_IFACE (self)->is_ready_func (self);
+
+#ifdef DBC /* ensure*/
+#endif
+
+	return retval;
+}
+
+/**
  * tny_account_start_operation:
  * @self: a #TnyAccount object
  * @domain: the domain of the #TnyStatus instances that will happen in @status_callback
Index: libtinymail/tny-account.h
===================================================================
--- libtinymail/tny-account.h	(revision 2535)
+++ libtinymail/tny-account.h	(working copy)
@@ -102,6 +102,7 @@
 	gboolean (*matches_url_string_func) (TnyAccount *self, const gchar *url_string);
 	void (*start_operation_func) (TnyAccount *self, TnyStatusDomain domain, TnyStatusCode code, TnyStatusCallback status_callback, gpointer status_user_data);
 	void (*stop_operation_func) (TnyAccount *self, gboolean *canceled);
+	gboolean (*is_ready_func) (TnyAccount *self);
 
 	/* Signals*/
 	void (*connection_status_changed) (TnyAccount *self, TnyConnectionStatus status);
@@ -136,7 +137,9 @@
 gboolean tny_account_matches_url_string (TnyAccount *self, const gchar *url_string);
 void tny_account_start_operation (TnyAccount *self, TnyStatusDomain domain, TnyStatusCode code, TnyStatusCallback status_callback, gpointer status_user_data);
 void tny_account_stop_operation (TnyAccount *self, gboolean *canceled);
+gboolean tny_account_is_ready (TnyAccount *self);
 
+
 G_END_DECLS
 
 #endif


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