[balsa] balsa-mailbox-node: Use modern macros



commit 8b7f607259a6ceccbdba438730130fbff0707fd2
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date:   Fri Jul 26 20:41:38 2019 -0400

    balsa-mailbox-node: Use modern macros
    
    Use modern macros to declare and define.
    
    * src/mailbox-node.h: declare BalsaMailboxNode final;
    * src/mailbox-node.c: use G_DEFINE_TYPE();
      (balsa_mailbox_node_class_init),
      (balsa_mailbox_node_init), (get_parent_folder_name),
      (add_imap_entry), (handle_imap_path), (mark_imap_path),
      (balsa_mailbox_node_set_dir), (balsa_mailbox_node_set_name),
      (balsa_mailbox_node_set_config_prefix),
      (balsa_mailbox_node_set_last_use_time),
      (balsa_mailbox_node_change_style): adapt;
      (balsa_mailbox_node_set_list_inbox),
      (balsa_mailbox_node_set_subscribed),
      (balsa_mailbox_node_set_scanned), (balsa_mailbox_node_get_mailbox),
      (balsa_mailbox_node_get_name),
      (balsa_mailbox_node_get_config_prefix),
      (balsa_mailbox_node_get_last_use_time),
      (balsa_mailbox_node_get_server), (balsa_mailbox_node_get_style),
      (balsa_mailbox_node_get_subscribed),
      (balsa_mailbox_node_get_scanned),
      (balsa_mailbox_node_get_list_inbox),
      (balsa_mailbox_node_get_delim), (balsa_mailbox_node_get_dir),
      (balsa_mailbox_node_get_parent): new functions;
    * libbalsa/folder-scanners.h:
    * libinit_balsa/assistant_page_user.c (create_imap_mbx):
    * src/balsa-app.c (find_mailbox), (find_path), (find_url),
      (balsa_find_mailbox_by_url), (balsa_get_short_mailbox_name),
      (balsa_find_iter_by_data_func), (ba_remove_children_mailbox_nodes),
      (balsa_remove_children_mailbox_nodes):
    * src/balsa-index.c (bndx_destroy), (bndx_selection_changed_idle),
      (bndx_selection_changed), (bndx_find_current_msgno),
      (bndx_scroll_on_open_idle), (balsa_index_load_mailbox_node),
      (bndx_search_iter), (bndx_search_iter_and_select),
      (bndx_mailbox_changed_idle), (balsa_index_selected_msgnos_new),
      (balsa_index_selected_msgnos_free), (bndx_view_source),
      (bndx_compose_foreach), (bndx_compose_from_list), (bndx_do_delete),
      (balsa_message_move_to_trash), (balsa_find_notebook_page_num),
      (balsa_index_toggle_flag), (bi_toggle_deleted_cb), (mru_menu_cb),
      (bndx_do_popup), (balsa_index_set_thread_messages),
      (balsa_index_set_view_filter), (balsa_index_transfer),
      (balsa_index_expunge), (bndx_next_msgno), (balsa_index_pipe),
      (balsa_index_select_thread), (balsa_index_set_last_use_time),
      (balsa_index_get_last_use_time), (balsa_index_get_mailbox):
    * src/balsa-mblist.c (bmbl_selection_func), (bmbl_tree_expand),
      (bmbl_tree_collapse_helper), (bmbl_tree_collapse),
      (bmbl_row_compare), (bmbl_drag_cb), (bmbl_select_mailbox),
      (bmbl_row_activated_cb), (bmbl_find_all_unread_mboxes_func),
      (get_lru_descendant), (bmbl_real_disconnect_mbnode_signals),
      (bmbl_store_redraw_mbnode), (bmbl_node_style),
      (bmbl_mru_selected_cb), (bmbl_mru_activated_cb),

 ChangeLog                           |  75 +++++++++++
 libbalsa/folder-scanners.h          |   2 +-
 libinit_balsa/assistant_page_user.c |   2 +-
 src/balsa-app.c                     |  59 +++++---
 src/balsa-index.c                   | 101 +++++++-------
 src/balsa-mblist.c                  | 119 +++++++++--------
 src/filter-edit-callbacks.c         |   2 +-
 src/folder-conf.c                   | 172 +++++++++++++-----------
 src/mailbox-conf.c                  |  21 +--
 src/mailbox-node.c                  | 259 +++++++++++++++++++++++++++++-------
 src/mailbox-node.h                  |  81 ++++++-----
 src/main-window.c                   |  36 ++---
 src/main.c                          |  15 ++-
 src/pref-manager.c                  |  23 ++--
 src/save-restore.c                  |  41 ++++--
 src/save-restore.h                  |   2 +-
 16 files changed, 657 insertions(+), 353 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 36b1b5647..59132d64c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,78 @@
+2019-07-26  Peter Bloomfield  <pbloomfield bellsouth net>
+
+       balsa-mailbox-node: Use modern macros to declare and define.
+
+       * src/mailbox-node.h: declare BalsaMailboxNode final;
+       * src/mailbox-node.c: use G_DEFINE_TYPE();
+       (balsa_mailbox_node_class_init),
+       (balsa_mailbox_node_init), (get_parent_folder_name),
+       (add_imap_entry), (handle_imap_path), (mark_imap_path),
+       (balsa_mailbox_node_set_dir), (balsa_mailbox_node_set_name),
+       (balsa_mailbox_node_set_config_prefix),
+       (balsa_mailbox_node_set_last_use_time),
+       (balsa_mailbox_node_change_style): adapt;
+       (balsa_mailbox_node_set_list_inbox),
+       (balsa_mailbox_node_set_subscribed),
+       (balsa_mailbox_node_set_scanned), (balsa_mailbox_node_get_mailbox),
+       (balsa_mailbox_node_get_name),
+       (balsa_mailbox_node_get_config_prefix),
+       (balsa_mailbox_node_get_last_use_time),
+       (balsa_mailbox_node_get_server), (balsa_mailbox_node_get_style),
+       (balsa_mailbox_node_get_subscribed),
+       (balsa_mailbox_node_get_scanned),
+       (balsa_mailbox_node_get_list_inbox),
+       (balsa_mailbox_node_get_delim), (balsa_mailbox_node_get_dir),
+       (balsa_mailbox_node_get_parent): new functions;
+       * libbalsa/folder-scanners.h:
+       * libinit_balsa/assistant_page_user.c (create_imap_mbx):
+       * src/balsa-app.c (find_mailbox), (find_path), (find_url),
+       (balsa_find_mailbox_by_url), (balsa_get_short_mailbox_name),
+       (balsa_find_iter_by_data_func), (ba_remove_children_mailbox_nodes),
+       (balsa_remove_children_mailbox_nodes):
+       * src/balsa-index.c (bndx_destroy), (bndx_selection_changed_idle),
+       (bndx_selection_changed), (bndx_find_current_msgno),
+       (bndx_scroll_on_open_idle), (balsa_index_load_mailbox_node),
+       (bndx_search_iter), (bndx_search_iter_and_select),
+       (bndx_mailbox_changed_idle), (balsa_index_selected_msgnos_new),
+       (balsa_index_selected_msgnos_free), (bndx_view_source),
+       (bndx_compose_foreach), (bndx_compose_from_list), (bndx_do_delete),
+       (balsa_message_move_to_trash), (balsa_find_notebook_page_num),
+       (balsa_index_toggle_flag), (bi_toggle_deleted_cb), (mru_menu_cb),
+       (bndx_do_popup), (balsa_index_set_thread_messages),
+       (balsa_index_set_view_filter), (balsa_index_transfer),
+       (balsa_index_expunge), (bndx_next_msgno), (balsa_index_pipe),
+       (balsa_index_select_thread), (balsa_index_set_last_use_time),
+       (balsa_index_get_last_use_time), (balsa_index_get_mailbox):
+       * src/balsa-mblist.c (bmbl_selection_func), (bmbl_tree_expand),
+       (bmbl_tree_collapse_helper), (bmbl_tree_collapse),
+       (bmbl_row_compare), (bmbl_drag_cb), (bmbl_select_mailbox),
+       (bmbl_row_activated_cb), (bmbl_find_all_unread_mboxes_func),
+       (get_lru_descendant), (bmbl_real_disconnect_mbnode_signals),
+       (bmbl_store_redraw_mbnode), (bmbl_node_style),
+       (bmbl_mru_selected_cb), (bmbl_mru_activated_cb),
+       (balsa_mblist_mailbox_node_append):
+       * src/filter-edit-callbacks.c (update_filters_mailbox):
+       * src/folder-conf.c (folder_conf_clicked_ok),
+       (folder_conf_imap_subscriptions), (folder_conf_imap_node),
+       (validate_sub_folder), (browse_button_cb),
+       (subfolder_conf_clicked_ok), (folder_conf_imap_sub_node),
+       (folder_conf_delete), (folder_conf_add_imap_sub_cb):
+       * src/mailbox-conf.c (mailbox_conf_delete_cb),
+       (mailbox_conf_delete), (run_mailbox_conf), (mailbox_conf_edit):
+       * src/main-window.c (bw_enable_mailbox_menus),
+       (bw_notebook_label_new), (bw_real_open_mbnode_idle_cb),
+       (bw_real_open_mbnode_thread), (balsa_window_real_open_mbnode),
+       (balsa_window_real_close_mbnode), (bw_check_mailbox_list),
+       (bw_add_mbox_to_checklist), (mw_mbox_change_connection_status),
+       (bw_change_connection_status_idle), (balsa_window_update_tab):
+       * src/main.c (periodic_expunge_cb):
+       * src/pref-manager.c (add_other_server), (server_del_cb),
+       (update_mail_servers):
+       * src/save-restore.c (folder_section_path),
+       (migrate_imap_mailboxes), (config_folder_delete),
+       (config_folder_init):
+       * src/save-restore.h: use them.
+
 2019-07-23  Peter Bloomfield  <pbloomfield bellsouth net>
 
        filter-run: Make filter-run.h private
diff --git a/libbalsa/folder-scanners.h b/libbalsa/folder-scanners.h
index 857b55bfb..d67e62624 100644
--- a/libbalsa/folder-scanners.h
+++ b/libbalsa/folder-scanners.h
@@ -31,7 +31,7 @@ typedef gpointer LocalHandler(gpointer root, const char *d_name,
 typedef gboolean ImapCheck(const char *fn, LibBalsaServer * server,
                            guint depth);
 typedef void ImapMark(const char *fn, gpointer data);
-typedef void ImapHandler(const char *fn, char delim, gint noselect,
+typedef void ImapHandler(const char *fn, gint delim, gint noselect,
                         gint marked, gint noscan, gpointer data);
 
 /* read_dir used by mailbox-node append-subtree callback */
diff --git a/libinit_balsa/assistant_page_user.c b/libinit_balsa/assistant_page_user.c
index 128378a78..f6652b258 100644
--- a/libinit_balsa/assistant_page_user.c
+++ b/libinit_balsa/assistant_page_user.c
@@ -233,7 +233,7 @@ create_imap_mbx(const gchar *name, const gchar* host, NetClientCryptMode securit
     libbalsa_server_set_host(server, host, security);
     libbalsa_server_set_remember_password(server, remember);
     mbnode = balsa_mailbox_node_new_imap_folder(server, NULL);
-    mbnode->name = g_strdup(name != NULL && name[0] != '\0' ? name : host);
+    balsa_mailbox_node_set_name(mbnode, name != NULL && name[0] != '\0' ? name : host);
 
     config_folder_add(mbnode, NULL);
     /* memory leak? */
diff --git a/src/balsa-app.c b/src/balsa-app.c
index ac50ae951..ba82eb4ca 100644
--- a/src/balsa-app.c
+++ b/src/balsa-app.c
@@ -610,7 +610,7 @@ find_mailbox(GtkTreeModel * model, GtkTreePath * path, GtkTreeIter * iter,
     BalsaMailboxNode *mbnode;
 
     gtk_tree_model_get(model, iter, 0, &mbnode, -1);
-    if (mbnode->mailbox == bf->data) {
+    if (balsa_mailbox_node_get_mailbox(mbnode) == bf->data) {
        bf->mbnode = mbnode;
        return TRUE;
     }
@@ -648,8 +648,8 @@ find_path(GtkTreeModel * model, GtkTreePath * path, GtkTreeIter * iter,
     BalsaMailboxNode *mbnode;
 
     gtk_tree_model_get(model, iter, 0, &mbnode, -1);
-    if (mbnode->server == bf->server &&
-        g_strcmp0(mbnode->dir, bf->data) == 0) {
+    if (balsa_mailbox_node_get_server(mbnode) == bf->server &&
+        g_strcmp0(balsa_mailbox_node_get_dir(mbnode), bf->data) == 0) {
        bf->mbnode = mbnode;
        return TRUE;
     }
@@ -680,7 +680,7 @@ find_url(GtkTreeModel * model, GtkTreePath * path, GtkTreeIter * iter,
     LibBalsaMailbox *mailbox;
 
     gtk_tree_model_get(model, iter, 0, &mbnode, -1);
-    if ((mailbox = mbnode->mailbox) != NULL &&
+    if ((mailbox = balsa_mailbox_node_get_mailbox(mbnode)) != NULL &&
         strcmp(libbalsa_mailbox_get_url(mailbox), bf->data) == 0) {
         bf->mbnode = mbnode;
         return TRUE;
@@ -730,7 +730,7 @@ balsa_find_mailbox_by_url(const gchar * url)
     LibBalsaMailbox *mailbox = NULL;
 
     if ((mbnode = balsa_find_url(url))) {
-       mailbox = mbnode->mailbox;
+       mailbox = balsa_mailbox_node_get_mailbox(mbnode);
        g_object_unref(mbnode);
     }
     return mailbox;
@@ -747,21 +747,27 @@ gchar*
 balsa_get_short_mailbox_name(const gchar *url)
 {
     BalsaMailboxNode *mbnode;
-    gchar *short_name;
+    gchar *short_name = NULL;
 
-    if ((mbnode = balsa_find_url(url)) != NULL && mbnode->mailbox != NULL) {
-        const gchar *name = libbalsa_mailbox_get_name(mbnode->mailbox);
+    if ((mbnode = balsa_find_url(url)) != NULL) {
+        LibBalsaMailbox *mailbox = balsa_mailbox_node_get_mailbox(mbnode);
 
-        if (mbnode->server) {
-            short_name = g_strconcat(libbalsa_server_get_host(mbnode->server), ":",
+        if (mailbox != NULL) {
+            const gchar *name = libbalsa_mailbox_get_name(mailbox);
+            LibBalsaServer *server = balsa_mailbox_node_get_server(mbnode);
+
+            if (server != NULL) {
+                short_name = g_strconcat(libbalsa_server_get_host(server), ":",
                                      name, NULL);
-        } else {
-            short_name = g_strdup(name);
+            } else {
+                short_name = g_strdup(name);
+            }
         }
-    } else {
-        short_name = g_strdup(url);
     }
 
+    if (short_name == NULL)
+        short_name = g_strdup(url);
+
     return short_name;
 }
 
@@ -781,7 +787,7 @@ balsa_find_iter_by_data_func(GtkTreeModel * model, GtkTreePath * path,
     gtk_tree_model_get(model, iter, 0, &mbnode, -1);
     if(!mbnode)
         return FALSE;
-    if (mbnode == bf->data || mbnode->mailbox == bf->data) {
+    if (mbnode == bf->data || balsa_mailbox_node_get_mailbox(mbnode) == bf->data) {
        *bf->iter = *iter;
        bf->found = TRUE;
     }
@@ -828,9 +834,12 @@ ba_remove_children_mailbox_nodes(GtkTreeModel * model, GtkTreeIter * parent,
        return;
 
     do {
+        LibBalsaMailbox *mailbox;
+
        gtk_tree_model_get(model, &iter, 0, &mbnode, -1);
-       if (mbnode->parent) {
-           LibBalsaMailbox *mailbox = mbnode->mailbox;
+       mailbox = balsa_mailbox_node_get_mailbox(mbnode);
+
+       if (balsa_mailbox_node_get_parent(mbnode) != NULL) {
            if (mailbox == balsa_app.inbox
                || mailbox == balsa_app.outbox
                || mailbox == balsa_app.sentbox
@@ -844,8 +853,10 @@ ba_remove_children_mailbox_nodes(GtkTreeModel * model, GtkTreeIter * parent,
                gtk_tree_store_remove(balsa_app.mblist_tree_store, &iter);
        } else {
            printf("sparing %s %s\n",
-                  mbnode->mailbox ? "mailbox" : "folder ",
-                  mbnode->mailbox ? libbalsa_mailbox_get_name(mbnode->mailbox) : mbnode->name);
+                  mailbox != NULL ? "mailbox" : "folder ",
+                  mailbox != NULL ?
+                   libbalsa_mailbox_get_name(mailbox) :
+                   balsa_mailbox_node_get_name(mbnode));
            valid = gtk_tree_model_iter_next(model, &iter);
        }
        g_object_unref(mbnode);
@@ -860,9 +871,13 @@ balsa_remove_children_mailbox_nodes(BalsaMailboxNode * mbnode)
     GtkTreeIter *iter = NULL;
     GSList *specials = NULL, *l;
 
-    if (balsa_app.debug)
-       printf("Destroying children of %p %s\n",
-              mbnode, mbnode && mbnode->name ? mbnode->name : "");
+    if (balsa_app.debug) {
+        const gchar *name;
+
+       printf("Destroying children of %p %s\n", mbnode,
+               (mbnode != NULL &&
+                (name = balsa_mailbox_node_get_name(mbnode)) != NULL) ? name : "");
+    }
 
     if (mbnode && balsa_find_iter_by_data(&parent, mbnode))
        iter = &parent;
diff --git a/src/balsa-index.c b/src/balsa-index.c
index caf56ef91..d794508ed 100644
--- a/src/balsa-index.c
+++ b/src/balsa-index.c
@@ -218,7 +218,7 @@ bndx_destroy(GObject * obj)
     if (index->mailbox_node) {
        LibBalsaMailbox* mailbox;
 
-       if ((mailbox = index->mailbox_node->mailbox)) {
+       if ((mailbox = balsa_mailbox_node_get_mailbox(index->mailbox_node)) != NULL) {
            g_signal_handlers_disconnect_matched(mailbox,
                                                 G_SIGNAL_MATCH_DATA,
                                                 0, 0, NULL, NULL, index);
@@ -505,7 +505,7 @@ bndx_selection_changed_idle(BalsaIndex * index)
 
     if (!index->mailbox_node)
         return FALSE;
-    mailbox = index->mailbox_node->mailbox;
+    mailbox = balsa_mailbox_node_get_mailbox(index->mailbox_node);
     selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(index));
 
     /* Save next_msgno, because changing flags may zero it. */
@@ -569,7 +569,7 @@ bndx_selection_changed(GtkTreeSelection * selection, BalsaIndex * index)
     if (index->current_msgno) {
         GtkTreePath *path;
 
-        if (libbalsa_mailbox_msgno_find(index->mailbox_node->mailbox,
+        if (libbalsa_mailbox_msgno_find(balsa_mailbox_node_get_mailbox(index->mailbox_node),
                                         index->current_msgno,
                                         &path, NULL)) {
             gboolean update_preview = TRUE;
@@ -676,7 +676,7 @@ bndx_find_current_msgno(BalsaIndex * bindex,
                         GtkTreePath ** path , GtkTreeIter * iter)
 {
     return bindex->current_msgno > 0
-        && libbalsa_mailbox_msgno_find(bindex->mailbox_node->mailbox,
+        && libbalsa_mailbox_msgno_find(balsa_mailbox_node_get_mailbox(bindex->mailbox_node),
                                        bindex->current_msgno, path, iter);
 }
 
@@ -816,7 +816,7 @@ bndx_scroll_on_open_idle(BalsaIndex *index)
         return FALSE;
 
     balsa_index_update_tree(index, balsa_app.expand_tree);
-    mailbox = index->mailbox_node->mailbox;
+    mailbox = balsa_mailbox_node_get_mailbox(index->mailbox_node);
     first_unread = libbalsa_mailbox_get_first_unread(mailbox);
     if (first_unread > 0) {
        unsigned msgno = first_unread;
@@ -947,7 +947,7 @@ bndx_mailbox_message_expunged_cb(LibBalsaMailbox * mailbox, guint msgno,
 
 /* balsa_index_load_mailbox_node:
  *
- * mbnode->mailbox is already open
+ * balsa_mailbox_node_get_mailbox(mbnode) is already open
  */
 
 gboolean
@@ -960,9 +960,9 @@ balsa_index_load_mailbox_node(BalsaIndex * index,
     g_return_val_if_fail(BALSA_IS_INDEX(index), TRUE);
     g_return_val_if_fail(index->mailbox_node == NULL, TRUE);
     g_return_val_if_fail(BALSA_IS_MAILBOX_NODE(mbnode), TRUE);
-    g_return_val_if_fail(LIBBALSA_IS_MAILBOX(mbnode->mailbox), TRUE);
 
-    mailbox = mbnode->mailbox;
+    mailbox = balsa_mailbox_node_get_mailbox(mbnode);
+    g_return_val_if_fail(LIBBALSA_IS_MAILBOX(mailbox), TRUE);
 
     /*
      * set the new mailbox
@@ -1001,7 +1001,7 @@ balsa_index_load_mailbox_node(BalsaIndex * index,
                                              LIBBALSA_MESSAGE_FLAG_DELETED);
     index->search_iter = libbalsa_mailbox_search_iter_new(cond_undeleted);
     /* Note when this mailbox was opened, for use in auto-closing. */
-    time(&index->mailbox_node->last_use);
+    balsa_mailbox_node_set_last_use_time(index->mailbox_node);
 
     return FALSE;
 }
@@ -1110,14 +1110,14 @@ bndx_search_iter(BalsaIndex * index,
                 BndxSearchViewable viewable,
                 guint stop_msgno)
 {
+    LibBalsaMailbox *mailbox = balsa_mailbox_node_get_mailbox(index->mailbox_node);
     gboolean found;
 
     do {
        GtkTreePath *path;
 
        found =
-           libbalsa_mailbox_search_iter_step(index->mailbox_node->mailbox,
-                                             search_iter, iter,
+           libbalsa_mailbox_search_iter_step(mailbox, search_iter, iter,
                                              direction ==
                                              BNDX_SEARCH_DIRECTION_NEXT,
                                              stop_msgno);
@@ -1126,9 +1126,7 @@ bndx_search_iter(BalsaIndex * index,
        if (viewable == BNDX_SEARCH_VIEWABLE_ANY)
            break;
 
-       path = gtk_tree_model_get_path(GTK_TREE_MODEL
-                                      (index->mailbox_node->mailbox),
-                                      iter);
+       path = gtk_tree_model_get_path(GTK_TREE_MODEL(mailbox), iter);
        found = bndx_row_is_viewable(index, path);
        gtk_tree_path_free(path);
     } while (!found);
@@ -1148,7 +1146,7 @@ bndx_search_iter_and_select(BalsaIndex * index,
     guint stop_msgno;
 
     if (!((index->next_msgno > 0
-           && libbalsa_mailbox_msgno_find(index->mailbox_node->mailbox,
+           && libbalsa_mailbox_msgno_find(balsa_mailbox_node_get_mailbox(index->mailbox_node),
                                           index->next_msgno, NULL, &iter))
           || (start == BNDX_SEARCH_START_ANY
               && bndx_find_root(index, &iter))))
@@ -1370,7 +1368,7 @@ bndx_mailbox_changed_idle(BalsaIndex * bindex)
 
     bindex->has_mailbox_changed_idle = FALSE;
 
-    mailbox = bindex->mailbox_node->mailbox;
+    mailbox = balsa_mailbox_node_get_mailbox(bindex->mailbox_node);
     first_unread = libbalsa_mailbox_get_first_unread(mailbox);
     if (first_unread > 0
         && libbalsa_mailbox_msgno_find(mailbox, first_unread,
@@ -1440,14 +1438,14 @@ balsa_index_selected_msgnos_new(BalsaIndex * index)
     gtk_tree_selection_selected_foreach(selection,
                                         (GtkTreeSelectionForeachFunc)
                                         bndx_selected_msgnos_func, msgnos);
-    libbalsa_mailbox_register_msgnos(index->mailbox_node->mailbox, msgnos);
+    libbalsa_mailbox_register_msgnos(balsa_mailbox_node_get_mailbox(index->mailbox_node), msgnos);
     return msgnos;
 }
 
 void
 balsa_index_selected_msgnos_free(BalsaIndex * index, GArray * msgnos)
 {
-    libbalsa_mailbox_unregister_msgnos(index->mailbox_node->mailbox,
+    libbalsa_mailbox_unregister_msgnos(balsa_mailbox_node_get_mailbox(index->mailbox_node),
                                        msgnos);
     g_array_free(msgnos, TRUE);
 }
@@ -1456,7 +1454,7 @@ static void
 bndx_view_source(gpointer data)
 {
     BalsaIndex *index = BALSA_INDEX(data);
-    LibBalsaMailbox *mailbox = index->mailbox_node->mailbox;
+    LibBalsaMailbox *mailbox = balsa_mailbox_node_get_mailbox(index->mailbox_node);
     guint i;
     GArray *selected = balsa_index_selected_msgnos_new(index);
 
@@ -1525,7 +1523,7 @@ balsa_index_selected_list(BalsaIndex * index)
 static void
 bndx_compose_foreach(BalsaIndex * index, SendType send_type)
 {
-    LibBalsaMailbox *mailbox = index->mailbox_node->mailbox;
+    LibBalsaMailbox *mailbox = balsa_mailbox_node_get_mailbox(index->mailbox_node);
     GArray *selected;
     guint i;
     guint skipped = 0U;
@@ -1605,7 +1603,7 @@ bndx_compose_from_list(BalsaIndex * index, SendType send_type)
 {
     GArray *selected = balsa_index_selected_msgnos_new(index);
     BalsaSendmsg *sm =
-        sendmsg_window_new_from_list(index->mailbox_node->mailbox,
+        sendmsg_window_new_from_list(balsa_mailbox_node_get_mailbox(index->mailbox_node),
                                      selected, send_type);
 
     balsa_index_selected_msgnos_free(index, selected);
@@ -1645,7 +1643,7 @@ bndx_do_delete(BalsaIndex* index, gboolean move_to_trash)
     BalsaIndex *trash = balsa_find_index_by_mailbox(balsa_app.trash);
     GArray *selected = balsa_index_selected_msgnos_new(index);
     GArray *messages;
-    LibBalsaMailbox *mailbox = index->mailbox_node->mailbox;
+    LibBalsaMailbox *mailbox = balsa_mailbox_node_get_mailbox(index->mailbox_node);
     guint i;
 
     messages = g_array_new(FALSE, FALSE, sizeof(guint));
@@ -1693,7 +1691,7 @@ balsa_message_move_to_trash(gpointer user_data)
     bndx_do_delete(index, TRUE);
     /* Note when message was flagged as deleted, for use in
      * auto-expunge. */
-    time(&index->mailbox_node->last_use);
+    balsa_mailbox_node_set_last_use_time(index->mailbox_node);
 }
 
 gint
@@ -1710,9 +1708,11 @@ balsa_find_notebook_page_num(LibBalsaMailbox * mailbox)
           gtk_notebook_get_nth_page(GTK_NOTEBOOK(balsa_app.notebook), i));
          i++) {
         GtkWidget *index = gtk_bin_get_child(GTK_BIN(page));
+        BalsaMailboxNode *mbnode;
 
-        if (index && BALSA_INDEX(index)->mailbox_node
-            && BALSA_INDEX(index)->mailbox_node->mailbox == mailbox)
+        if (index != NULL &&
+            (mbnode = BALSA_INDEX(index)->mailbox_node) != NULL &&
+            balsa_mailbox_node_get_mailbox(mbnode) == mailbox)
             return i;
     }
 
@@ -1726,7 +1726,7 @@ balsa_find_notebook_page_num(LibBalsaMailbox * mailbox)
 void
 balsa_index_toggle_flag(BalsaIndex* index, LibBalsaMessageFlag flag)
 {
-    LibBalsaMailbox *mailbox = index->mailbox_node->mailbox;
+    LibBalsaMailbox *mailbox = balsa_mailbox_node_get_mailbox(index->mailbox_node);
     int is_all_flagged = TRUE;
     GArray *selected = balsa_index_selected_msgnos_new(index);
     guint i;
@@ -1748,7 +1748,7 @@ balsa_index_toggle_flag(BalsaIndex* index, LibBalsaMessageFlag flag)
     if (flag == LIBBALSA_MESSAGE_FLAG_DELETED)
        /* Note when deleted flag was changed, for use in
         * auto-expunge. */
-       time(&index->mailbox_node->last_use);
+       balsa_mailbox_node_set_last_use_time(index->mailbox_node);
 }
 
 static void
@@ -1764,7 +1764,7 @@ bi_toggle_deleted_cb(gpointer user_data, GtkWidget * widget)
 
     selected = balsa_index_selected_msgnos_new(index);
     if (widget == index->undelete_item && selected->len > 0) {
-       LibBalsaMailbox *mailbox = index->mailbox_node->mailbox;
+       LibBalsaMailbox *mailbox = balsa_mailbox_node_get_mailbox(index->mailbox_node);
         guint msgno = g_array_index(selected, guint, 0);
         if (libbalsa_mailbox_msgno_has_flags(mailbox, msgno,
                                              LIBBALSA_MESSAGE_FLAG_DELETED,
@@ -1803,7 +1803,7 @@ mru_menu_cb(const gchar * url, BalsaIndex * index)
 
     g_return_if_fail(mailbox != NULL);
 
-    if (index->mailbox_node->mailbox != mailbox) {
+    if (balsa_mailbox_node_get_mailbox(index->mailbox_node) != mailbox) {
         GArray *selected = balsa_index_selected_msgnos_new(index);
         balsa_index_transfer(index, selected, mailbox, FALSE);
         balsa_index_selected_msgnos_free(index, selected);
@@ -1946,7 +1946,7 @@ bndx_do_popup(BalsaIndex * index, GdkEventButton * event)
 
     BALSA_DEBUG();
 
-    mailbox = index->mailbox_node->mailbox;
+    mailbox = balsa_mailbox_node_get_mailbox(index->mailbox_node);
     for (i = 0; i < selected->len; i++) {
         guint msgno = g_array_index(selected, guint, i);
         if (libbalsa_mailbox_msgno_has_flags(mailbox, msgno,
@@ -1964,7 +1964,6 @@ bndx_do_popup(BalsaIndex * index, GdkEventButton * event)
         gtk_widget_set_sensitive(GTK_WIDGET(list->data), any);
     g_list_free(l);
 
-    mailbox = index->mailbox_node->mailbox;
     readonly = libbalsa_mailbox_get_readonly(mailbox);
     gtk_widget_set_sensitive(index->delete_item,
                              any_not_deleted && !readonly);
@@ -2068,7 +2067,7 @@ balsa_index_set_thread_messages(BalsaIndex * index,
 
     g_return_if_fail(index != NULL);
     g_return_if_fail(index->mailbox_node != NULL);
-    mailbox = index->mailbox_node->mailbox;
+    mailbox = balsa_mailbox_node_get_mailbox(index->mailbox_node);
     g_return_if_fail(mailbox != NULL);
 
     if (thread_messages) {
@@ -2099,7 +2098,7 @@ balsa_index_set_view_filter(BalsaIndex * bindex, int filter_no,
     LibBalsaMailbox *mailbox;
 
     g_return_if_fail(BALSA_IS_INDEX(bindex));
-    mailbox = bindex->mailbox_node->mailbox;
+    mailbox = balsa_mailbox_node_get_mailbox(bindex->mailbox_node);
 
     g_free(bindex->filter_string);
     bindex->filter_no = filter_no;
@@ -2134,7 +2133,7 @@ balsa_index_transfer(BalsaIndex *index, GArray * msgnos,
     if (msgnos->len == 0)
         return;
 
-    from_mailbox = index->mailbox_node->mailbox;
+    from_mailbox = balsa_mailbox_node_get_mailbox(index->mailbox_node);
     success = copy ?
         libbalsa_mailbox_messages_copy(from_mailbox, msgnos, to_mailbox, &e) :
         libbalsa_mailbox_messages_move(from_mailbox, msgnos, to_mailbox, &e);
@@ -2160,7 +2159,7 @@ balsa_index_transfer(BalsaIndex *index, GArray * msgnos,
     if (!copy)
        /* Note when message was flagged as deleted, for use in
         * auto-expunge. */
-       time(&index->mailbox_node->last_use);
+       balsa_mailbox_node_set_last_use_time(index->mailbox_node);
 }
 
 /* General helpers. */
@@ -2251,7 +2250,7 @@ balsa_index_expunge(BalsaIndex * index)
 
     g_return_if_fail(index != NULL);
 
-    mailbox = index->mailbox_node->mailbox;
+    mailbox = balsa_mailbox_node_get_mailbox(index->mailbox_node);
     if (libbalsa_mailbox_get_readonly(mailbox))
        return;
 
@@ -2268,7 +2267,7 @@ bndx_next_msgno(BalsaIndex * index, guint current_msgno,
                 LibBalsaMailboxSearchIter * search_iter,
                 BndxSearchDirection direction)
 {
-    LibBalsaMailbox *mailbox = index->mailbox_node->mailbox;
+    LibBalsaMailbox *mailbox = balsa_mailbox_node_get_mailbox(index->mailbox_node);
     GtkTreeModel *model = GTK_TREE_MODEL(mailbox);
     GtkTreeIter iter;
     guint msgno = 0;
@@ -2651,6 +2650,7 @@ bndx_pipe_response(GtkWidget * dialog, gint response,
 void
 balsa_index_pipe(BalsaIndex * index)
 {
+    LibBalsaMailbox *mailbox;
     struct bndx_mailbox_info *info;
     GtkWidget *label, *entry;
     GtkWidget *dialog;
@@ -2659,22 +2659,23 @@ balsa_index_pipe(BalsaIndex * index)
 
     g_return_if_fail(BALSA_IS_INDEX(index));
     g_return_if_fail(BALSA_IS_MAILBOX_NODE(index->mailbox_node));
-    g_return_if_fail(LIBBALSA_IS_MAILBOX(index->mailbox_node->mailbox));
 
-    info =
-        g_object_get_data(G_OBJECT(index->mailbox_node->mailbox),
-                          BALSA_INDEX_PIPE_INFO);
+    mailbox = balsa_mailbox_node_get_mailbox(index->mailbox_node);
+    g_return_if_fail(LIBBALSA_IS_MAILBOX(mailbox));
+
+    info = g_object_get_data(G_OBJECT(mailbox), BALSA_INDEX_PIPE_INFO);
     if (info) {
         gtk_window_present_with_time(GTK_WINDOW(info->dialog),
                                      gtk_get_current_event_time());
         return;
     }
 
-    if(!libbalsa_mailbox_open(index->mailbox_node->mailbox, NULL))
+    if (!libbalsa_mailbox_open(mailbox, NULL))
        return;
+
     info = g_new(struct bndx_mailbox_info, 1);
     info->bindex = index;
-    info->mailbox = index->mailbox_node->mailbox;
+    info->mailbox = mailbox;
     g_object_set_data_full(G_OBJECT(info->mailbox), BALSA_INDEX_PIPE_INFO,
                            info, bndx_mailbox_notify);
 
@@ -2791,16 +2792,17 @@ balsa_index_count_selected_messages(BalsaIndex * bindex)
 void
 balsa_index_select_thread(BalsaIndex * bindex)
 {
+    LibBalsaMailbox *mailbox = balsa_mailbox_node_get_mailbox(bindex->mailbox_node);
+    GtkTreeModel *model = GTK_TREE_MODEL(mailbox);
     GtkTreeIter iter;
-    GtkTreeModel *model = GTK_TREE_MODEL(bindex->mailbox_node->mailbox);
     GtkTreeIter next_iter;
     GtkTreePath *path;
     GtkTreeSelection *selection =
         gtk_tree_view_get_selection(GTK_TREE_VIEW(bindex));
     gboolean valid;
 
-    if (!bindex->current_msgno
-        || !libbalsa_mailbox_msgno_find(bindex->mailbox_node->mailbox,
+    if (bindex->current_msgno == 0
+        || !libbalsa_mailbox_msgno_find(mailbox,
                                         bindex->current_msgno, NULL,
                                         &iter))
         return;
@@ -2895,7 +2897,7 @@ balsa_index_set_last_use_time(BalsaIndex *bindex)
     g_return_if_fail(BALSA_IS_INDEX(bindex));
 
     if (bindex->mailbox_node != NULL)
-        time(&bindex->mailbox_node->last_use);
+        balsa_mailbox_node_set_last_use_time(bindex->mailbox_node);
 }
 
 time_t
@@ -2903,7 +2905,8 @@ balsa_index_get_last_use_time(BalsaIndex *bindex)
 {
     g_return_val_if_fail(BALSA_IS_INDEX(bindex), 0);
 
-    return bindex->mailbox_node != NULL ? bindex->mailbox_node->last_use : 0;
+    return bindex->mailbox_node != NULL ?
+        balsa_mailbox_node_get_last_use_time(bindex->mailbox_node) : 0;
 }
 
 LibBalsaMailbox *
@@ -2911,5 +2914,5 @@ balsa_index_get_mailbox(BalsaIndex *bindex)
 {
     g_return_val_if_fail(BALSA_IS_INDEX(bindex), NULL);
 
-    return bindex->mailbox_node != NULL ? bindex->mailbox_node->mailbox : NULL;
+    return bindex->mailbox_node != NULL ? balsa_mailbox_node_get_mailbox(bindex->mailbox_node) : NULL;
 }
diff --git a/src/balsa-mblist.c b/src/balsa-mblist.c
index 4ac3c25fe..1a7ea535d 100644
--- a/src/balsa-mblist.c
+++ b/src/balsa-mblist.c
@@ -487,8 +487,12 @@ bmbl_selection_func(GtkTreeSelection * selection, GtkTreeModel * model,
     /* If the node is selected, allow it to be deselected, whether or
      * not it has a mailbox (if it doesn't, it shouldn't have been
      * selected in the first place, but you never know...). */
-    retval = (path_currently_selected || (mbnode && mbnode->mailbox));
+    retval = (path_currently_selected ||
+              (mbnode != NULL &&
+               balsa_mailbox_node_get_mailbox(mbnode) != NULL));
+
     g_object_unref(mbnode);
+
     return retval;
 }
 
@@ -517,7 +521,7 @@ bmbl_tree_expand(GtkTreeView * tree_view, GtkTreeIter * iter,
     gtk_tree_model_get(model, iter, MBNODE_COLUMN, &mbnode, -1);
     balsa_mailbox_node_scan_children(mbnode);
 
-    if (!mbnode->mailbox)
+    if (balsa_mailbox_node_get_mailbox(mbnode) == NULL)
         gtk_tree_store_set(GTK_TREE_STORE(model), iter,
                            ICON_COLUMN,
                            balsa_icon_id(BALSA_PIXMAP_MBOX_DIR_OPEN),
@@ -534,16 +538,19 @@ bmbl_tree_expand(GtkTreeView * tree_view, GtkTreeIter * iter,
        gboolean first_mailbox = TRUE;
 
         do {
+            LibBalsaMailbox *mailbox;
+
             gtk_tree_model_get(model, &child_iter,
                                MBNODE_COLUMN, &mbnode, -1);
-            if (mbnode && mbnode->mailbox) {
+            if (mbnode != NULL &&
+                (mailbox = balsa_mailbox_node_get_mailbox(mbnode)) != NULL) {
                /* Mark only one mailbox as exposed. */
                if (first_mailbox) {
-                   libbalsa_mailbox_set_exposed(mbnode->mailbox, TRUE);
+                   libbalsa_mailbox_set_exposed(mailbox, TRUE);
                    first_mailbox = FALSE;
                } else
-                   libbalsa_mailbox_set_exposed(mbnode->mailbox, FALSE);
-               if (mbnode->mailbox == current_mailbox) {
+                   libbalsa_mailbox_set_exposed(mailbox, FALSE);
+               if (mailbox == current_mailbox) {
                    GtkTreeSelection *selection =
                        gtk_tree_view_get_selection(tree_view);
                    g_signal_handlers_block_by_func(selection,
@@ -569,11 +576,12 @@ bmbl_tree_collapse_helper(GtkTreeModel * model, GtkTreeIter * iter)
     if (gtk_tree_model_iter_children(model, &child_iter, iter)) {
         do {
             BalsaMailboxNode *mbnode;
+            LibBalsaMailbox *mailbox;
 
             gtk_tree_model_get(model, &child_iter,
                                MBNODE_COLUMN, &mbnode, -1);
-            if (mbnode->mailbox)
-               libbalsa_mailbox_set_exposed(mbnode->mailbox, FALSE);
+            if ((mailbox = balsa_mailbox_node_get_mailbox(mbnode)) != NULL)
+               libbalsa_mailbox_set_exposed(mailbox, FALSE);
            g_object_unref(mbnode);
             bmbl_tree_collapse_helper(model, &child_iter);
         } while (gtk_tree_model_iter_next(model, &child_iter));
@@ -589,7 +597,7 @@ bmbl_tree_collapse(GtkTreeView * tree_view, GtkTreeIter * iter,
 
     gtk_tree_model_get(model, iter, MBNODE_COLUMN, &mbnode, -1);
 
-    if (!mbnode->mailbox)
+    if (balsa_mailbox_node_get_mailbox(mbnode) == NULL)
         gtk_tree_store_set(GTK_TREE_STORE(model), iter,
                            ICON_COLUMN,
                            balsa_icon_id(BALSA_PIXMAP_MBOX_DIR_CLOSED),
@@ -622,12 +630,12 @@ bmbl_row_compare(GtkTreeModel * model, GtkTreeIter * iter1,
 
     gtk_tree_model_get(model, iter1,
                        MBNODE_COLUMN, &mbnode, NAME_COLUMN, &name1, -1);
-    m1 = mbnode->mailbox;
+    m1 = balsa_mailbox_node_get_mailbox(mbnode);
     g_object_unref(mbnode);
 
     gtk_tree_model_get(model, iter2,
                        MBNODE_COLUMN, &mbnode, NAME_COLUMN, &name2, -1);
-    m2 = mbnode->mailbox;
+    m2 = balsa_mailbox_node_get_mailbox(mbnode);
     g_object_unref(mbnode);
 
     switch (sort_column) {
@@ -832,7 +840,7 @@ bmbl_drag_cb(GtkWidget * widget, GdkDragContext * context,
 
         gtk_tree_model_get_iter(model, &iter, path);
         gtk_tree_model_get(model, &iter, MBNODE_COLUMN, &mbnode, -1);
-        mailbox = mbnode->mailbox;
+        mailbox = balsa_mailbox_node_get_mailbox(mbnode);
        g_object_unref(mbnode);
 
         /* cannot transfer to the originating mailbox */
@@ -871,7 +879,7 @@ bmbl_select_mailbox(GtkTreeSelection * selection, gpointer data)
            BalsaMailboxNode *mbnode;
            LibBalsaMailbox *mailbox;
            gtk_tree_model_get(model, &iter, MBNODE_COLUMN, &mbnode, -1);
-           mailbox = mbnode->mailbox;
+           mailbox = balsa_mailbox_node_get_mailbox(mbnode);
            g_object_unref(mbnode);
            if (MAILBOX_OPEN(mailbox))
                /* Opening a mailbox under program control. */
@@ -909,15 +917,15 @@ bmbl_select_mailbox(GtkTreeSelection * selection, gpointer data)
     }
 
     if (gtk_tree_selection_path_is_selected(selection, path)) {
-        BalsaMailboxNode *mbnode;
         GtkTreeIter iter;
+        BalsaMailboxNode *mbnode;
+        LibBalsaMailbox *mailbox;
 
         gtk_tree_model_get_iter(model, &iter, path);
         gtk_tree_model_get(model, &iter, MBNODE_COLUMN, &mbnode, -1);
-        g_return_if_fail(mbnode != NULL);
 
-        if (mbnode->mailbox)
-            balsa_mblist_open_mailbox(mbnode->mailbox);
+        if ((mailbox = balsa_mailbox_node_get_mailbox(mbnode)) != NULL)
+            balsa_mblist_open_mailbox(mailbox);
        g_object_unref(mbnode);
     }
     gtk_tree_path_free(path);
@@ -939,13 +947,14 @@ bmbl_row_activated_cb(GtkTreeView * tree_view, GtkTreePath * path,
     GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
     GtkTreeIter iter;
     BalsaMailboxNode *mbnode;
+    LibBalsaMailbox *mailbox;
 
     gtk_tree_model_get_iter(model, &iter, path);
     gtk_tree_model_get(model, &iter, MBNODE_COLUMN, &mbnode, -1);
     g_return_if_fail(mbnode != NULL);
 
-    if (mbnode->mailbox)
-        balsa_mblist_open_mailbox(mbnode->mailbox);
+    if ((mailbox = balsa_mailbox_node_get_mailbox(mbnode)) != NULL)
+        balsa_mblist_open_mailbox(mailbox);
     g_object_unref(mbnode);
 }
 
@@ -1072,7 +1081,7 @@ bmbl_find_all_unread_mboxes_func(GtkTreeModel * model, GtkTreePath * path,
     gtk_tree_model_get(model, iter, MBNODE_COLUMN, &mbnode, -1);
     if(!mbnode) /* this node has no MBNODE associated at this time */
         return FALSE;
-    mailbox = mbnode->mailbox;
+    mailbox = balsa_mailbox_node_get_mailbox(mbnode);
     g_object_unref(mbnode);
 
     if (mailbox
@@ -1191,19 +1200,23 @@ get_lru_descendant(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
 {
     struct lru_data *dt  = (struct lru_data*)data;
     BalsaMailboxNode *mbnode;
+    LibBalsaMailbox *mailbox;
 
-    if(!gtk_tree_path_is_descendant(path, dt->ancestor_path))
+    if (!gtk_tree_path_is_descendant(path, dt->ancestor_path))
         return FALSE;
+
     gtk_tree_model_get(model, iter, MBNODE_COLUMN, &mbnode, -1);
-    if(mbnode->mailbox && libbalsa_mailbox_is_open(mbnode->mailbox) &&
-       (!dt->mbnode || (mbnode->last_use < dt->mbnode->last_use)) )
-    {
-        if (dt->mbnode)
-            g_object_unref(dt->mbnode);
-        dt->mbnode = mbnode;
+
+    if ((mailbox = balsa_mailbox_node_get_mailbox(mbnode)) != NULL &&
+        libbalsa_mailbox_is_open(mailbox) &&
+        (dt->mbnode == NULL ||
+         (balsa_mailbox_node_get_last_use_time(mbnode) <
+          balsa_mailbox_node_get_last_use_time(dt->mbnode)))) {
+        g_set_object(&dt->mbnode, mbnode);
     }
 
-    else g_object_unref(mbnode);
+    g_object_unref(mbnode);
+
     return FALSE;
 }
 
@@ -1270,8 +1283,10 @@ static void
 bmbl_real_disconnect_mbnode_signals(BalsaMailboxNode * mbnode,
                                    GtkTreeModel * model)
 {
-    if (mbnode->mailbox)
-        g_signal_handlers_disconnect_by_func(mbnode->mailbox,
+    LibBalsaMailbox *mailbox;
+
+    if ((mailbox = balsa_mailbox_node_get_mailbox(mbnode)) != NULL)
+        g_signal_handlers_disconnect_by_func(mailbox,
                                              G_CALLBACK
                                              (bmbl_mailbox_changed_cb),
                                              NULL);
@@ -1285,15 +1300,13 @@ bmbl_real_disconnect_mbnode_signals(BalsaMailboxNode * mbnode,
 static gboolean
 bmbl_store_redraw_mbnode(GtkTreeIter * iter, BalsaMailboxNode * mbnode)
 {
+    LibBalsaMailbox *mailbox;
     const gchar *icon;
     const gchar *name;
     gchar *tmp = NULL;
     gboolean expose = FALSE;
 
-    g_return_val_if_fail(mbnode, FALSE);
-
-    if (mbnode->mailbox) {
-        LibBalsaMailbox *mailbox = mbnode->mailbox;
+    if ((mailbox = balsa_mailbox_node_get_mailbox(mbnode)) != NULL) {
        static guint mailbox_changed_signal = 0;
 
        if (LIBBALSA_IS_MAILBOX_POP3(mailbox)) {
@@ -1340,10 +1353,10 @@ bmbl_store_redraw_mbnode(GtkTreeIter * iter, BalsaMailboxNode * mbnode)
        if (!mailbox_changed_signal)
            mailbox_changed_signal =
                g_signal_lookup("changed", LIBBALSA_TYPE_MAILBOX);
-       if (!g_signal_has_handler_pending(G_OBJECT(mbnode->mailbox),
+       if (!g_signal_has_handler_pending(G_OBJECT(mailbox),
                                           mailbox_changed_signal, 0, TRUE)) {
            /* Now we have a mailbox: */
-           g_signal_connect(mbnode->mailbox, "changed",
+           g_signal_connect(mailbox, "changed",
                             G_CALLBACK(bmbl_mailbox_changed_cb),
                             NULL);
             if (libbalsa_mailbox_get_unread(mailbox) > 0
@@ -1354,12 +1367,12 @@ bmbl_store_redraw_mbnode(GtkTreeIter * iter, BalsaMailboxNode * mbnode)
                               0, TRUE);
            /* If necessary, expand rows to expose this mailbox after
             * setting its mbnode in the tree-store. */
-           expose = libbalsa_mailbox_get_exposed(mbnode->mailbox);
+           expose = libbalsa_mailbox_get_exposed(mailbox);
        }
     } else {
        /* new directory, but not a mailbox */
        icon = BALSA_PIXMAP_MBOX_DIR_CLOSED;
-        name = tmp = g_path_get_basename(mbnode->name);
+        name = tmp = g_path_get_basename(balsa_mailbox_node_get_name(mbnode));
     }
 
     gtk_tree_store_set(balsa_app.mblist_tree_store, iter,
@@ -1373,7 +1386,7 @@ bmbl_store_redraw_mbnode(GtkTreeIter * iter, BalsaMailboxNode * mbnode)
                        -1);
     g_free(tmp);
 
-    if (mbnode->mailbox) {
+    if (mailbox != NULL) {
        GtkTreeModel *model = GTK_TREE_MODEL(balsa_app.mblist_tree_store);
        if (expose) {
            GtkTreePath *path = gtk_tree_model_get_path(model, iter);
@@ -1448,10 +1461,10 @@ bmbl_node_style(GtkTreeModel * model, GtkTreeIter * iter)
     gchar *text_total = NULL;
 
     gtk_tree_model_get(model, iter, MBNODE_COLUMN, &mbnode, -1);
-    if (!mbnode || !mbnode->mailbox)
+    if (mbnode == NULL ||
+        (mailbox = balsa_mailbox_node_get_mailbox(mbnode)) != NULL)
         return;
 
-    mailbox = mbnode->mailbox;
     unread_messages = libbalsa_mailbox_get_unread(mailbox);
     total_messages = libbalsa_mailbox_get_total(mailbox);
 
@@ -1482,13 +1495,13 @@ bmbl_node_style(GtkTreeModel * model, GtkTreeIter * iter)
                 : mailbox_name;
 
             weight = PANGO_WEIGHT_BOLD;
-            mbnode->style |= MBNODE_STYLE_NEW_MAIL;
+            balsa_mailbox_node_change_style(mbnode, MBNODE_STYLE_NEW_MAIL, 0);
         } else {
             icon = (mailbox == balsa_app.inbox) ?
                 BALSA_PIXMAP_MBOX_IN : BALSA_PIXMAP_MBOX_TRAY_EMPTY;
             name = mailbox_name;
             weight = PANGO_WEIGHT_NORMAL;
-            mbnode->style &= ~MBNODE_STYLE_NEW_MAIL;
+            balsa_mailbox_node_change_style(mbnode, 0, MBNODE_STYLE_NEW_MAIL);
         }
 
         gtk_tree_store_set(GTK_TREE_STORE(model), iter,
@@ -1528,18 +1541,18 @@ bmbl_node_style(GtkTreeModel * model, GtkTreeIter * iter)
            do {
                BalsaMailboxNode *mn;
                gtk_tree_model_get(model, &child, MBNODE_COLUMN, &mn, -1);
-               if (mn->style & (MBNODE_STYLE_NEW_MAIL |
-                                MBNODE_STYLE_UNREAD_CHILD))
+               if ((balsa_mailbox_node_get_style(mn) &
+                     (MBNODE_STYLE_NEW_MAIL | MBNODE_STYLE_UNREAD_CHILD)) != 0)
                    has_unread_child = TRUE;
                g_object_unref(mn);
            } while (!has_unread_child && gtk_tree_model_iter_next(model, &child));
        }
        if (has_unread_child) {
-           mbnode->style |= MBNODE_STYLE_UNREAD_CHILD;
+           balsa_mailbox_node_change_style(mbnode, MBNODE_STYLE_UNREAD_CHILD, 0);
            gtk_tree_store_set(GTK_TREE_STORE(model), &parent,
                               STYLE_COLUMN, PANGO_STYLE_OBLIQUE, -1);
        } else {
-           mbnode->style &= ~MBNODE_STYLE_UNREAD_CHILD;
+           balsa_mailbox_node_change_style(mbnode, 0, MBNODE_STYLE_UNREAD_CHILD);
            gtk_tree_store_set(GTK_TREE_STORE(model), &parent,
                               STYLE_COLUMN, PANGO_STYLE_NORMAL, -1);
        }
@@ -1930,7 +1943,8 @@ bmbl_mru_selected_cb(GtkTreeSelection * selection, gpointer data)
         model = gtk_tree_view_get_model(tree_view);
         gtk_tree_model_get_iter(model, &iter, path);
         gtk_tree_model_get(model, &iter, 0, &mbnode, -1);
-        ((BalsaMBListMRUEntry *) data)->url = g_strdup(libbalsa_mailbox_get_url(mbnode->mailbox));
+        ((BalsaMBListMRUEntry *) data)->url =
+            g_strdup(libbalsa_mailbox_get_url(balsa_mailbox_node_get_mailbox(mbnode)));
        g_object_unref(mbnode);
         bmbl_mru_activate_cb(NULL, data);
 
@@ -1957,14 +1971,15 @@ bmbl_mru_activated_cb(GtkTreeView * tree_view, GtkTreePath * path,
     GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
     GtkTreeIter iter;
     BalsaMailboxNode *mbnode;
+    LibBalsaMailbox *mailbox;
 
     gtk_tree_model_get_iter(model, &iter, path);
     gtk_tree_model_get(model, &iter, MBNODE_COLUMN, &mbnode, -1);
     g_return_if_fail(mbnode != NULL);
 
-    if (mbnode->mailbox) {
+    if ((mailbox = balsa_mailbox_node_get_mailbox(mbnode)) != NULL) {
         ((BalsaMBListMRUEntry *) data)->url =
-            g_strdup(libbalsa_mailbox_get_url(mbnode->mailbox));
+            g_strdup(libbalsa_mailbox_get_url(mailbox));
         bmbl_mru_activate_cb(NULL, data);
 
         gtk_dialog_response(GTK_DIALOG
@@ -2263,10 +2278,10 @@ balsa_mblist_mailbox_node_append(BalsaMailboxNode * root,
             gtk_tree_model_get_path(model, parent_iter);
         if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(balsa_app.mblist),
                                        parent_path)
-            && !mbnode->scanned) {
+            && !balsa_mailbox_node_get_scanned(mbnode)) {
             /* Check this node for children. */
             balsa_mailbox_node_append_subtree(mbnode);
-            mbnode->scanned = TRUE;
+            balsa_mailbox_node_set_scanned(mbnode, TRUE);
         }
         gtk_tree_path_free(parent_path);
     }
diff --git a/src/filter-edit-callbacks.c b/src/filter-edit-callbacks.c
index 96c2dd8f2..6094545b2 100644
--- a/src/filter-edit-callbacks.c
+++ b/src/filter-edit-callbacks.c
@@ -1332,7 +1332,7 @@ update_filters_mailbox(GtkTreeModel * model, GtkTreePath * path,
     gchar *tmp;
 
     gtk_tree_model_get(model, iter, 0, &mbnode, -1);
-    mailbox = mbnode->mailbox;
+    mailbox = balsa_mailbox_node_get_mailbox(mbnode);
     g_object_unref(mbnode);
     if (!mailbox)
        return FALSE;
diff --git a/src/folder-conf.c b/src/folder-conf.c
index e6cfe48cf..2f3d24526 100644
--- a/src/folder-conf.c
+++ b/src/folder-conf.c
@@ -245,12 +245,12 @@ folder_conf_clicked_ok(FolderDialogData * fcw)
                        (GDestroyNotify) folder_conf_destroy_cdd);
     }
 
-    g_free(fcw->mbnode->name);
-    fcw->mbnode->name = g_strdup(libbalsa_server_cfg_get_name(fcw->server_cfg));
-    fcw->mbnode->subscribed = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fcw->subscribed));
-    fcw->mbnode->list_inbox = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fcw->list_inbox));
-    g_free(fcw->mbnode->dir);
-    fcw->mbnode->dir = g_strdup(gtk_entry_get_text(GTK_ENTRY(fcw->prefix)));
+    balsa_mailbox_node_set_name(fcw->mbnode, libbalsa_server_cfg_get_name(fcw->server_cfg));
+    balsa_mailbox_node_set_dir(fcw->mbnode, gtk_entry_get_text(GTK_ENTRY(fcw->prefix)));
+    balsa_mailbox_node_set_subscribed(fcw->mbnode,
+                                      gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fcw->subscribed)));
+    balsa_mailbox_node_set_list_inbox(fcw->mbnode,
+                                      gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fcw->list_inbox)));
 
     libbalsa_server_config_changed(fcw->server); /* trigger config save */
     imap_update_subscriptions(fcw);
@@ -259,7 +259,8 @@ folder_conf_clicked_ok(FolderDialogData * fcw)
        balsa_mblist_mailbox_node_append(NULL, fcw->mbnode);
        balsa_mailbox_node_append_subtree(fcw->mbnode);
        config_folder_add(fcw->mbnode, NULL);
-       g_signal_connect_swapped(fcw->server, "config-changed", G_CALLBACK(config_folder_update), 
fcw->mbnode);
+       g_signal_connect_swapped(fcw->server, "config-changed",
+                                 G_CALLBACK(config_folder_update), fcw->mbnode);
        update_mail_servers();
     } else {
        balsa_mailbox_node_rescan(fcw->mbnode);
@@ -390,9 +391,13 @@ folder_conf_imap_subscriptions(GtkButton        *widget,
        gchar *label_str;
 
        label_str = g_strdup_printf(_("Manage folder subscriptions of IMAP server “%s”"),
-                       (fcw->mbnode != NULL) ? fcw->mbnode->name : _("unknown"));
-       dialog = create_imap_folder_dialog(fcw->server, GTK_WINDOW(fcw->dialog), "IMAPSubscriptions", TRUE, 
_("Manage subscriptions"),
-                       label_str, &fcw->store, &treeview);
+                                   (fcw->mbnode != NULL) ?
+                                     balsa_mailbox_node_get_name(fcw->mbnode) :
+                                     _("unknown"));
+       dialog = create_imap_folder_dialog(fcw->server, GTK_WINDOW(fcw->dialog),
+                                           "IMAPSubscriptions", TRUE,
+                                           _("Manage subscriptions"),
+                                           label_str, &fcw->store, &treeview);
        g_free(label_str);
 
        if (dialog != NULL) {
@@ -432,7 +437,7 @@ folder_conf_imap_node(BalsaMailboxNode *mn)
 
     fcw = g_new0(FolderDialogData, 1);
     if (mn != NULL) {
-       fcw->server = mn->server;
+       fcw->server = balsa_mailbox_node_get_server(mn);
     } else {
        fcw->server = g_object_new(LIBBALSA_TYPE_IMAP_SERVER, NULL);
     }
@@ -465,7 +470,7 @@ folder_conf_imap_node(BalsaMailboxNode *mn)
                                   (gpointer *) &fcw_new);
     }
 
-    fcw->server_cfg = libbalsa_server_cfg_new(fcw->server, (mn != NULL) ? mn->name : NULL);
+    fcw->server_cfg = libbalsa_server_cfg_new(fcw->server, (mn != NULL) ? balsa_mailbox_node_get_name(mn) : 
NULL);
     gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(fcw->dialog))), 
GTK_WIDGET(fcw->server_cfg));
     g_signal_connect(fcw->server_cfg, "changed", G_CALLBACK(validate_folder), fcw);
 
@@ -476,8 +481,9 @@ folder_conf_imap_node(BalsaMailboxNode *mn)
     button = gtk_button_new_with_label(_("Manage subscriptions…"));
     g_signal_connect(button, "clicked", G_CALLBACK(folder_conf_imap_subscriptions), fcw);
     if (mn != NULL) {
-       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fcw->subscribed), mn->subscribed);
-       gtk_widget_set_sensitive(button, mn->subscribed);
+        gboolean subscribed = balsa_mailbox_node_get_subscribed(mn);
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fcw->subscribed), subscribed);
+       gtk_widget_set_sensitive(button, subscribed);
     } else {
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fcw->subscribed), FALSE);
        gtk_widget_set_sensitive(button, FALSE);
@@ -487,9 +493,9 @@ folder_conf_imap_node(BalsaMailboxNode *mn)
     libbalsa_server_cfg_add_row(fcw->server_cfg, TRUE, box, NULL);
 
     fcw->list_inbox = libbalsa_server_cfg_add_check(fcw->server_cfg, TRUE, _("Always show _Inbox"),
-       (mn != NULL) ? mn->list_inbox : TRUE, NULL, NULL);
+       (mn != NULL) ? balsa_mailbox_node_get_list_inbox(mn) : TRUE, NULL, NULL);
     fcw->prefix = libbalsa_server_cfg_add_entry(fcw->server_cfg, TRUE, _("Pr_efix:"),
-       (mn != NULL) ? mn->dir : NULL, NULL, NULL);
+       (mn != NULL) ? balsa_mailbox_node_get_dir(mn) : NULL, NULL, NULL);
 
     /* additional advanced settings */
     fcw->connection_limit = gtk_spin_button_new_with_range(1.0, 40.0, 1.0);
@@ -530,9 +536,9 @@ validate_sub_folder(GtkWidget * w, SubfolderDialogData * sdd)
      * Allow typing in the parent_folder entry box only if we already
      * have the server information in mn:
      */
-    gboolean have_server = (mn && LIBBALSA_IS_IMAP_SERVER(mn->server));
-    gtk_editable_set_editable(GTK_EDITABLE(sdd->parent_folder),
-                             have_server);
+    gboolean have_server = (mn && LIBBALSA_IS_IMAP_SERVER(balsa_mailbox_node_get_server(mn)));
+    gtk_editable_set_editable(GTK_EDITABLE(sdd->parent_folder), have_server);
+    gtk_widget_set_can_focus(sdd->parent_folder, have_server);
     /*
      * We'll allow a null parent name, although some IMAP servers
      * will deny permission:
@@ -586,8 +592,8 @@ browse_button_cb(GtkWidget           *widget,
        gchar *label_str;
 
        label_str = g_strdup_printf(_("Select parent folder of “%s”"),
-                                    libbalsa_mailbox_get_name(sdd->mbnode->mailbox));
-       dialog = create_imap_folder_dialog(sdd->mbnode->server, GTK_WINDOW(sdd->dialog), "IMAPSelectParent", 
FALSE,
+                                    libbalsa_mailbox_get_name(balsa_mailbox_node_get_mailbox(sdd->mbnode)));
+       dialog = create_imap_folder_dialog(balsa_mailbox_node_get_server(sdd->mbnode), 
GTK_WINDOW(sdd->dialog), "IMAPSelectParent", FALSE,
                        _("Select parent folder"), label_str, &sdd->store, &treeview);
        g_free(label_str);
 
@@ -637,17 +643,18 @@ subfolder_conf_clicked_ok(SubfolderDialogData * sdd)
     gchar *parent, *folder;
     gboolean ret = TRUE;
 
-    parent =
-        gtk_editable_get_chars(GTK_EDITABLE(sdd->parent_folder), 0, -1);
+    parent = gtk_editable_get_chars(GTK_EDITABLE(sdd->parent_folder), 0, -1);
     folder = gtk_editable_get_chars(GTK_EDITABLE(sdd->folder_name), 0, -1);
     if(balsa_app.debug)
        g_print("sdd->old_parent=%s\nsdd->old_folder=%s\n",
                sdd->old_parent, sdd->old_folder);
 
     if (sdd->mbnode) {
+        LibBalsaMailbox *mailbox = balsa_mailbox_node_get_mailbox(sdd->mbnode);
+
         /* Views stuff. */
-        if (sdd->mbnode->mailbox)
-            mailbox_conf_view_check(sdd->mcv, sdd->mbnode->mailbox);
+        if (mailbox != NULL)
+            mailbox_conf_view_check(sdd->mcv, mailbox);
         
         /* rename */
         if (g_strcmp0(parent, sdd->old_parent) != 0 ||
@@ -685,6 +692,8 @@ folder, parent);
             }
             if (button == GTK_RESPONSE_OK) {
                 GError* err = NULL;
+                LibBalsaServer *server;
+
                 /* Close the mailbox before renaming,
                  * otherwise the rescan will try to close it
                  * under its old name.
@@ -692,8 +701,8 @@ folder, parent);
                 balsa_window_close_mbnode(balsa_app.main_window,
                                           sdd->mbnode);
                 if(!libbalsa_imap_rename_subfolder
-                   (LIBBALSA_MAILBOX_IMAP(sdd->mbnode->mailbox),
-                    parent, folder, sdd->mbnode->subscribed, &err)) {
+                   (LIBBALSA_MAILBOX_IMAP(balsa_mailbox_node_get_mailbox(sdd->mbnode)),
+                    parent, folder, balsa_mailbox_node_get_subscribed(sdd->mbnode), &err)) {
                     balsa_information(LIBBALSA_INFORMATION_ERROR,
                                       _("Folder rename failed. Reason: %s"),
                                       err ? err->message : "unknown");
@@ -701,27 +710,24 @@ folder, parent);
                     ret = FALSE;
                     goto error;
                 }
-                g_free(sdd->mbnode->dir);
-                sdd->mbnode->dir = g_strdup(parent);
+                balsa_mailbox_node_set_dir(sdd->mbnode, parent);
 
                 /*  Rescan as little of the tree as possible. */
-                if (sdd->old_parent
-                    && !strncmp(parent, sdd->old_parent, strlen(parent))) {
+                server = balsa_mailbox_node_get_server(sdd->parent);
+                if (sdd->old_parent != NULL
+                    && g_str_has_prefix(sdd->old_parent, parent)) {
                     /* moved it up the tree */
-                   BalsaMailboxNode *mbnode =
-                        balsa_find_dir(sdd->parent->server, parent);
-                    if (mbnode) {
+                   BalsaMailboxNode *mbnode = balsa_find_dir(server, parent);
+                    if (mbnode != NULL) {
                         balsa_mailbox_node_rescan(mbnode);
                        g_object_unref(mbnode);
                    } else
                         printf("Parent not found!?\n");
-                } else if (sdd->old_parent
-                           && !strncmp(parent, sdd->old_parent,
-                                       strlen(sdd->old_parent))) {
+                } else if (sdd->old_parent != NULL
+                           && g_str_has_prefix(parent, sdd->old_parent)) {
                     /* moved it down the tree */
-                   BalsaMailboxNode *mbnode =
-                       balsa_find_dir(sdd->parent->server, sdd->old_parent);
-                    if (mbnode) {
+                   BalsaMailboxNode *mbnode = balsa_find_dir(server, sdd->old_parent);
+                    if (mbnode != NULL) {
                         balsa_mailbox_node_rescan(mbnode);
                        g_object_unref(mbnode);
                    }
@@ -729,19 +735,23 @@ folder, parent);
                     /* moved it sideways: a chain of folders might
                      * go away, so we'd better rescan the complete IMAP server
                      */
-                    BalsaMailboxNode *mb = sdd->mbnode->parent;
-                    while ((mb->mailbox != NULL) && (mb->parent != NULL))
-                        mb = mb->parent;
-                    balsa_mailbox_node_rescan(mb);
+                   BalsaMailboxNode *mbnode = balsa_mailbox_node_get_parent(sdd->mbnode);
+                   BalsaMailboxNode *parent_mbnode;
+
+                    while ((balsa_mailbox_node_get_mailbox(mbnode) != NULL) &&
+                           ((parent_mbnode = balsa_mailbox_node_get_parent(mbnode)) != NULL))
+                        mbnode = parent_mbnode;
+                    balsa_mailbox_node_rescan(mbnode);
                 }
             }
         }
     } else {
         GError *err = NULL;
         /* create and subscribe, if parent was. */
-        if(libbalsa_imap_new_subfolder(parent, folder,
-                                       sdd->parent->subscribed,
-                                       sdd->parent->server, &err)) {
+        if (libbalsa_imap_new_subfolder(parent, folder,
+                                        balsa_mailbox_node_get_subscribed(sdd->parent),
+                                        balsa_mailbox_node_get_server(sdd->parent),
+                                        &err)) {
             /* see it as server sees it: */
             balsa_mailbox_node_rescan(sdd->parent);
         } else {
@@ -774,6 +784,8 @@ folder_conf_imap_sub_node(BalsaMailboxNode * mn)
 {
     GtkWidget *grid, *button, *label, *hbox;
     SubfolderDialogData *sdd;
+    LibBalsaMailbox *mailbox;
+    LibBalsaServer *server;
     static SubfolderDialogData *sdd_new = NULL;
     guint row;
 
@@ -789,19 +801,22 @@ folder_conf_imap_sub_node(BalsaMailboxNode * mn)
 
     sdd = g_new0(SubfolderDialogData, 1);
     sdd->ok = (CommonDialogFunc) subfolder_conf_clicked_ok;
-
     sdd->mbnode = mn;
-       /* update */
-       if (!mn->mailbox) {
-            balsa_information(LIBBALSA_INFORMATION_ERROR,
-                              _("An IMAP folder that is not a mailbox\n"
-                                "has no properties that can be changed."));
-            g_free(sdd);
-           return;
-       }
-       sdd->parent = mn->parent;
-       sdd->old_folder = libbalsa_mailbox_get_name(mn->mailbox);
-    sdd->old_parent = sdd->mbnode ? sdd->mbnode->parent->dir : NULL;
+
+    mailbox = balsa_mailbox_node_get_mailbox(mn);
+    /* update */
+    if (mailbox == NULL) {
+        balsa_information(LIBBALSA_INFORMATION_ERROR,
+                          _("An IMAP folder that is not a mailbox\n"
+                            "has no properties that can be changed."));
+        g_free(sdd);
+
+        return;
+    }
+
+    sdd->parent = balsa_mailbox_node_get_parent(mn);
+    sdd->old_folder = libbalsa_mailbox_get_name(mailbox);
+    sdd->old_parent = balsa_mailbox_node_get_dir(sdd->parent);
 
     sdd->dialog = 
         GTK_DIALOG(gtk_dialog_new_with_buttons
@@ -849,8 +864,9 @@ folder_conf_imap_sub_node(BalsaMailboxNode * mn)
     ++row;
     (void) libbalsa_create_grid_label(_("Host:"), grid, row);
     sdd->host_label =
-        gtk_label_new(sdd->mbnode && sdd->mbnode->server
-                      ? libbalsa_server_get_host(sdd->mbnode->server) : "");
+        gtk_label_new((sdd->mbnode != NULL &&
+                       (server = balsa_mailbox_node_get_server(sdd->mbnode)) != NULL)
+                      ? libbalsa_server_get_host(server) : "");
     gtk_widget_set_halign(sdd->host_label, GTK_ALIGN_START);
     gtk_widget_set_hexpand(sdd->host_label, TRUE);
     gtk_grid_attach(GTK_GRID(grid), sdd->host_label, 1, row, 1, 1);
@@ -859,6 +875,7 @@ folder_conf_imap_sub_node(BalsaMailboxNode * mn)
     (void) libbalsa_create_grid_label(_("Subfolder of:"), grid, row);
     sdd->parent_folder = gtk_entry_new();
     gtk_editable_set_editable(GTK_EDITABLE(sdd->parent_folder), FALSE);
+    gtk_widget_set_can_focus(sdd->parent_folder, FALSE);
     gtk_entry_set_text(GTK_ENTRY(sdd->parent_folder), sdd->old_parent);
 
     button = gtk_button_new_with_mnemonic(_("_Browse…"));
@@ -889,14 +906,14 @@ folder_conf_imap_sub_node(BalsaMailboxNode * mn)
         (void) libbalsa_create_grid_label(_("Permissions:"), grid, row);
 
         /* mailbox closed: no detailed permissions available */
-        readonly = libbalsa_mailbox_get_readonly(mn->mailbox);
-        if (!libbalsa_mailbox_imap_is_connected(LIBBALSA_MAILBOX_IMAP(mn->mailbox))) {
+        readonly = libbalsa_mailbox_get_readonly(mailbox);
+        if (!libbalsa_mailbox_imap_is_connected(LIBBALSA_MAILBOX_IMAP(mailbox))) {
             rights_str = g_string_new(std_acls[readonly ? 1 : 3]);
             rights_str =
                 g_string_append(rights_str,
                                 _("\ndetailed permissions are available only for open folders"));
         } else {
-            rights = libbalsa_imap_get_rights(LIBBALSA_MAILBOX_IMAP(mn->mailbox));
+            rights = libbalsa_imap_get_rights(LIBBALSA_MAILBOX_IMAP(mailbox));
             if (!rights) {
                 rights_str = g_string_new(std_acls[readonly ? 1 : 3]);
                 rights_str =
@@ -918,8 +935,7 @@ folder_conf_imap_sub_node(BalsaMailboxNode * mn)
                                            std_acls[n + 1], rights);
 
                 /* acl's - only available if I have admin privileges */
-                if ((acls =
-                     libbalsa_imap_get_acls(LIBBALSA_MAILBOX_IMAP(mn->mailbox)))) {
+                if ((acls = libbalsa_imap_get_acls(LIBBALSA_MAILBOX_IMAP(mailbox)))) {
                     int uid;
 
                     for (uid = 0; acls[uid]; uid += 2) {
@@ -951,12 +967,12 @@ folder_conf_imap_sub_node(BalsaMailboxNode * mn)
         (void) libbalsa_create_grid_label(_("Quota:"), grid, row);
 
         /* mailbox closed: no quota available */
-        if (!libbalsa_mailbox_imap_is_connected(LIBBALSA_MAILBOX_IMAP(mn->mailbox)))
+        if (!libbalsa_mailbox_imap_is_connected(LIBBALSA_MAILBOX_IMAP(mailbox)))
             quotas = g_strdup(_("quota information available only for open folders"));
         else {
             gulong max, used;
 
-            if (!libbalsa_imap_get_quota(LIBBALSA_MAILBOX_IMAP(mn->mailbox), &max, &used))
+            if (!libbalsa_imap_get_quota(LIBBALSA_MAILBOX_IMAP(mailbox), &max, &used))
                 quotas = g_strdup(_("the server does not support quotas"));
             else if (max == 0 && used == 0)
                 quotas = g_strdup(_("no limits"));
@@ -976,7 +992,7 @@ folder_conf_imap_sub_node(BalsaMailboxNode * mn)
         gtk_grid_attach(GTK_GRID(grid), label, 1, row, 1, 1);
         g_free(quotas);
 
-        sdd->mcv = mailbox_conf_view_new(mn->mailbox,
+        sdd->mcv = mailbox_conf_view_new(mailbox,
                                          GTK_WINDOW(sdd->dialog),
                                          grid, 5,
                                          G_CALLBACK(set_ok_sensitive));
@@ -999,7 +1015,7 @@ folder_conf_delete(BalsaMailboxNode* mbnode)
     GtkWidget* ask;
     gint response;
 
-    if(!mbnode->config_prefix) {
+    if (balsa_mailbox_node_get_config_prefix(mbnode) == NULL) {
         balsa_information(LIBBALSA_INFORMATION_ERROR,
                          _("This folder is not stored in configuration. "
                            "I do not yet know how to remove it "
@@ -1014,7 +1030,7 @@ folder_conf_delete(BalsaMailboxNode* mbnode)
                                    "“%s” from the list.\n"
                                    "You may use “New IMAP Folder” "
                                    "later to add this folder again.\n"),
-                                 mbnode->name);
+                                 balsa_mailbox_node_get_name(mbnode));
 #if HAVE_MACOSX_DESKTOP
     libbalsa_macosx_menu_for_parent(ask, GTK_WINDOW(balsa_app.main_window));
 #endif
@@ -1068,7 +1084,8 @@ folder_conf_add_imap_sub_cb(GtkWidget * widget, gpointer data)
 
            row = 0;
            (void) libbalsa_create_grid_label(_("Subfolder of:"), grid, row);
-           plabel = gtk_label_new(mbnode->mailbox != NULL ? mbnode->dir : _("server (top level)"));
+           plabel = gtk_label_new(balsa_mailbox_node_get_mailbox(mbnode) != NULL ?
+                                   balsa_mailbox_node_get_dir(mbnode) : _("server (top level)"));
            gtk_widget_set_halign(plabel, GTK_ALIGN_START);
            gtk_widget_set_hexpand(plabel, TRUE);
            gtk_grid_attach(GTK_GRID(grid), plabel, 1, row++, 1, 1);
@@ -1079,17 +1096,22 @@ folder_conf_add_imap_sub_cb(GtkWidget * widget, gpointer data)
            result = gtk_dialog_run(GTK_DIALOG(dialog));
            if (result == GTK_RESPONSE_ACCEPT) {
                const gchar *new_name;
+                gint delim = balsa_mailbox_node_get_delim(mbnode);
 
                new_name = gtk_entry_get_text(GTK_ENTRY(name_entry));
-               if ((mbnode->delim != 0) && (strchr(new_name, mbnode->delim) != NULL)) {
+               if ((delim != 0) && (strchr(new_name, delim) != NULL)) {
                        balsa_information(LIBBALSA_INFORMATION_ERROR,
                                _("The character “%c” is used as hierarchy separator by the server "
                                  "and therefore not permitted in the folder name."),
-                                       mbnode->delim);
+                                delim);
                } else {
                        GError *err = NULL;
 
-                       if (libbalsa_imap_new_subfolder(mbnode->dir, new_name, mbnode->subscribed, 
mbnode->server, &err)) {
+                       if (libbalsa_imap_new_subfolder(balsa_mailbox_node_get_dir(mbnode),
+                                                        new_name,
+                                                        balsa_mailbox_node_get_subscribed(mbnode),
+                                                        balsa_mailbox_node_get_server(mbnode),
+                                                        &err)) {
                                /* see it as server sees it: */
                                balsa_mailbox_node_rescan(mbnode);
                        } else {
diff --git a/src/mailbox-conf.c b/src/mailbox-conf.c
index 219ebeb0b..5307cb90c 100644
--- a/src/mailbox-conf.c
+++ b/src/mailbox-conf.c
@@ -149,7 +149,7 @@ mailbox_conf_delete_cb(GtkWidget * widget, gpointer data)
     BalsaMailboxNode *mbnode =
         balsa_mblist_get_selected_node(balsa_app.mblist);
 
-    if (mbnode->mailbox == NULL)
+    if (balsa_mailbox_node_get_mailbox(mbnode) == NULL)
         balsa_information(LIBBALSA_INFORMATION_ERROR,
                            _("No mailbox selected."));
     else
@@ -175,7 +175,7 @@ mailbox_conf_delete(BalsaMailboxNode * mbnode)
 {
     gint button;
     GtkWidget *ask;
-    LibBalsaMailbox* mailbox = mbnode->mailbox;
+    LibBalsaMailbox* mailbox = balsa_mailbox_node_get_mailbox(mbnode);
     gchar *url, *group;
 
     if(BALSA_IS_MAILBOX_SPECIAL(mailbox)) {
@@ -273,15 +273,16 @@ mailbox_conf_delete(BalsaMailboxNode * mbnode)
     if (LIBBALSA_IS_MAILBOX_IMAP(mailbox) &&
         libbalsa_mailbox_get_config_prefix(mailbox) == NULL) {
         GError *err = NULL;
-       BalsaMailboxNode *parent = mbnode->parent;
+       BalsaMailboxNode *parent = balsa_mailbox_node_get_parent(mbnode);
         if(libbalsa_imap_delete_folder(LIBBALSA_MAILBOX_IMAP(mailbox),
                                        &err)) {
             /* a chain of folders might go away, so we'd better rescan from
              * higher up
              */
-            while (!parent->mailbox && parent->parent) {
+            while (balsa_mailbox_node_get_mailbox(parent) == NULL &&
+                   balsa_mailbox_node_get_parent(parent) != NULL) {
                 mbnode = parent;
-                parent = parent->parent;
+                parent = balsa_mailbox_node_get_parent(parent);
             }
             balsa_mblist_mailbox_node_remove(mbnode);
             balsa_mailbox_node_rescan(parent); /* see it as server sees it */
@@ -360,7 +361,7 @@ run_mailbox_conf(BalsaMailboxNode* mbnode, GType mailbox_type,
     if (update) {
         mcw->ok_handler = mailbox_conf_update;
         mcw->ok_button_name = _("_Update");
-        mcw->mailbox = mbnode->mailbox;
+        mcw->mailbox = balsa_mailbox_node_get_mailbox(mbnode);
     } else {
         mcw->ok_handler = mailbox_conf_add;
         mcw->ok_button_name = _("_Add");
@@ -411,9 +412,9 @@ mailbox_conf_edit(BalsaMailboxNode * mbnode)
 {
     GtkWidget *dialog;
 
-    g_return_if_fail(LIBBALSA_IS_MAILBOX(mbnode->mailbox));
+    g_return_if_fail(LIBBALSA_IS_MAILBOX(balsa_mailbox_node_get_mailbox(mbnode)));
 
-    dialog = g_object_get_data(G_OBJECT(mbnode->mailbox),
+    dialog = g_object_get_data(G_OBJECT(balsa_mailbox_node_get_mailbox(mbnode)),
                                BALSA_MAILBOX_CONF_DIALOG);
     if (dialog) {
         gtk_window_present_with_time(GTK_WINDOW(dialog),
@@ -422,9 +423,9 @@ mailbox_conf_edit(BalsaMailboxNode * mbnode)
     }
 
     dialog =
-        run_mailbox_conf(mbnode, G_OBJECT_TYPE(G_OBJECT(mbnode->mailbox)),
+        run_mailbox_conf(mbnode, G_OBJECT_TYPE(G_OBJECT(balsa_mailbox_node_get_mailbox(mbnode))),
                          TRUE);
-    g_object_set_data(G_OBJECT(mbnode->mailbox), BALSA_MAILBOX_CONF_DIALOG,
+    g_object_set_data(G_OBJECT(balsa_mailbox_node_get_mailbox(mbnode)), BALSA_MAILBOX_CONF_DIALOG,
                       dialog);
 }
 
diff --git a/src/mailbox-node.c b/src/mailbox-node.c
index b48af5493..f28bf9a36 100644
--- a/src/mailbox-node.c
+++ b/src/mailbox-node.c
@@ -50,9 +50,6 @@ struct imap_scan_item_ {
     unsigned scanned:1, selectable:1, marked:1;
 };
 
-static void balsa_mailbox_node_class_init(BalsaMailboxNodeClass *
-                                            klass);
-static void balsa_mailbox_node_init(BalsaMailboxNode * mn);
 static void balsa_mailbox_node_dispose(GObject * object);
 static void balsa_mailbox_node_finalize(GObject * object);
 
@@ -77,7 +74,7 @@ static BalsaMailboxNode *add_local_folder(BalsaMailboxNode * root,
                                          const char *d_name,
                                          const char *fn);
 
-static void handle_imap_path(const char *fn, char delim, int noselect,
+static void handle_imap_path(const char *fn, int delim, int noselect,
                             int noscan, int marked, void *data);
 static gint check_imap_path(const char *fn, LibBalsaServer * server,
                            guint depth);
@@ -93,31 +90,26 @@ enum {
 
 static guint balsa_mailbox_node_signals[LAST_SIGNAL];
 
-GType
-balsa_mailbox_node_get_type(void)
-{
-    static GType mailbox_node_type = 0;
-
-    if (!mailbox_node_type) {
-       static const GTypeInfo mailbox_node_info = {
-           sizeof(BalsaMailboxNodeClass),
-            NULL,               /* base_init */
-            NULL,               /* base_finalize */
-           (GClassInitFunc)  balsa_mailbox_node_class_init,
-            NULL,               /* class_finalize */
-            NULL,               /* class_data */
-           sizeof(BalsaMailboxNode),
-            0,                  /* n_preallocs */
-           (GInstanceInitFunc) balsa_mailbox_node_init
-       };
-
-       mailbox_node_type =
-           g_type_register_static(G_TYPE_OBJECT, "BalsaMailboxNode",
-                                   &mailbox_node_info, 0);
-    }
-    
-    return mailbox_node_type;
-}
+struct _BalsaMailboxNode {
+    GObject object;
+    BalsaMailboxNode *parent; /* NULL for root-level folders & mailboxes */
+    LibBalsaMailbox *mailbox; /* != NULL for leaves only */
+    gchar *name;       /* used for folders, i.e. when mailbox == NULL */
+    time_t last_use;   /* for closing least recently used mailboxes */
+    BalsaMailboxNodeStyle style;
+    /* folder data */
+    gchar* config_prefix;
+    gchar* dir;
+    LibBalsaServer * server; /* Used only by remote; is referenced */
+    int delim; /* IMAP delimiter so that we do not need to check it
+                * too often. */
+
+    unsigned subscribed:1;     /* Used only by remote */
+    unsigned list_inbox:1;     /* Used only by remote */
+    unsigned scanned:1;        /* IMAP flag */
+};
+
+G_DEFINE_TYPE(BalsaMailboxNode, balsa_mailbox_node, G_TYPE_OBJECT)
 
 static void
 balsa_mailbox_node_class_init(BalsaMailboxNodeClass * klass)
@@ -132,43 +124,29 @@ balsa_mailbox_node_class_init(BalsaMailboxNodeClass * klass)
        g_signal_new("save-config",
                      G_TYPE_FROM_CLASS(object_class),
                      G_SIGNAL_RUN_FIRST,
-                     G_STRUCT_OFFSET(BalsaMailboxNodeClass, save_config),
-                     NULL, NULL,
-                     NULL,
+                     0, NULL, NULL, NULL,
                     G_TYPE_NONE, 1,
                     G_TYPE_POINTER);
     balsa_mailbox_node_signals[LOAD_CONFIG] =
        g_signal_new("load-config",
                      G_TYPE_FROM_CLASS(object_class),
                      G_SIGNAL_RUN_FIRST,
-                     G_STRUCT_OFFSET(BalsaMailboxNodeClass, load_config),
-                     NULL, NULL,
-                     NULL,
+                     0, NULL, NULL, NULL,
                     G_TYPE_NONE, 1,
                     G_TYPE_POINTER);
     balsa_mailbox_node_signals[SHOW_PROP_DIALOG] =
        g_signal_new("show-prop-dialog",
                      G_TYPE_FROM_CLASS(object_class),
                      G_SIGNAL_RUN_LAST,
-                     G_STRUCT_OFFSET(BalsaMailboxNodeClass,
-                                     show_prop_dialog),
-                     NULL, NULL,
-                     NULL,
+                     0, NULL, NULL, NULL,
                     G_TYPE_NONE, 0);
     balsa_mailbox_node_signals[APPEND_SUBTREE] =
        g_signal_new("append-subtree",
                      G_TYPE_FROM_CLASS(object_class),
                      G_SIGNAL_RUN_FIRST,
-                     G_STRUCT_OFFSET(BalsaMailboxNodeClass, append_subtree),
-                     NULL, NULL,
-                     NULL,
+                     0, NULL, NULL, NULL,
                     G_TYPE_NONE, 0);
 
-    klass->save_config = balsa_mailbox_node_real_save_config;
-    klass->load_config = balsa_mailbox_node_real_load_config;
-    klass->show_prop_dialog = NULL;
-    klass->append_subtree   = NULL;
-
     object_class->dispose = balsa_mailbox_node_dispose;
     object_class->finalize = balsa_mailbox_node_finalize;
 }
@@ -184,6 +162,11 @@ balsa_mailbox_node_init(BalsaMailboxNode * mn)
     mn->config_prefix = NULL;
     mn->subscribed = FALSE;
     mn->scanned = FALSE;
+
+    g_signal_connect(mn, "save-config",
+                     G_CALLBACK(balsa_mailbox_node_real_save_config), NULL);
+    g_signal_connect(mn, "load-config",
+                     G_CALLBACK(balsa_mailbox_node_real_load_config), NULL);
 }
 
 static void
@@ -467,7 +450,7 @@ imap_scan_attach_mailbox(BalsaMailboxNode * mbnode, imap_scan_item * isi)
 typedef struct imap_scan_tree_ imap_scan_tree;
 struct imap_scan_tree_ {
     GSList *list;               /* a list of imap_scan_items */
-    char delim;
+    int delim;
 };
 
 static void imap_scan_destroy_tree(imap_scan_tree * tree);
@@ -1256,7 +1239,7 @@ add_local_folder(BalsaMailboxNode * root, const char *d_name,
  * IMAP folder scanner functions 
  * --------------------------------------------------------------------- */
 static gchar*
-get_parent_folder_name(const gchar* path, char delim)
+get_parent_folder_name(const gchar* path, gint delim)
 {
     const gchar* last_delim = strrchr(path, delim);
     return last_delim ? g_strndup(path, last_delim-path)
@@ -1336,7 +1319,7 @@ imap_scan_create_mbnode(BalsaMailboxNode * root, imap_scan_item * isi,
    add given mailbox unless its base name begins on dot.
 */
 static void
-add_imap_entry(const char *fn, char delim, gboolean noscan,
+add_imap_entry(const char *fn, int delim, gboolean noscan,
               gboolean selectable, gboolean marked, void *data)
 {
     imap_scan_tree *tree = (imap_scan_tree *) data;
@@ -1367,7 +1350,7 @@ imap_scan_destroy_tree(imap_scan_tree * tree)
 }
 
 static void
-handle_imap_path(const char *fn, char delim, int noselect, int noscan,
+handle_imap_path(const char *fn, int delim, int noselect, int noscan,
                 int marked, void *data)
 {
     if (!noselect) {
@@ -1432,3 +1415,177 @@ mark_imap_path(const gchar * fn, gpointer data)
        g_debug("… not found.");
     }
 }
+
+/*
+ * Setters
+ */
+
+void
+balsa_mailbox_node_set_dir(BalsaMailboxNode * mbnode, const gchar * dir)
+{
+    g_return_if_fail(BALSA_IS_MAILBOX_NODE(mbnode));
+
+    g_free(mbnode->dir);
+    mbnode->dir = g_strdup(dir);
+}
+
+void
+balsa_mailbox_node_set_name(BalsaMailboxNode * mbnode, const gchar * name)
+{
+    g_return_if_fail(BALSA_IS_MAILBOX_NODE(mbnode));
+
+    g_free(mbnode->name);
+    mbnode->name = g_strdup(name);
+}
+
+void
+balsa_mailbox_node_set_config_prefix(BalsaMailboxNode * mbnode, const gchar * config_prefix)
+{
+    g_return_if_fail(BALSA_IS_MAILBOX_NODE(mbnode));
+
+    g_free(mbnode->config_prefix);
+    mbnode->config_prefix = g_strdup(config_prefix);
+}
+
+void
+balsa_mailbox_node_set_last_use_time(BalsaMailboxNode * mbnode)
+{
+    g_return_if_fail(BALSA_IS_MAILBOX_NODE(mbnode));
+
+    time(&mbnode->last_use);
+}
+
+void
+balsa_mailbox_node_change_style(BalsaMailboxNode * mbnode,
+                                BalsaMailboxNodeStyle set,
+                                BalsaMailboxNodeStyle clear)
+{
+    g_return_if_fail(BALSA_IS_MAILBOX_NODE(mbnode));
+
+    mbnode->style |= set;
+    mbnode->style &= ~clear;
+}
+
+void
+balsa_mailbox_node_set_list_inbox(BalsaMailboxNode * mbnode, guint list_inbox)
+{
+    g_return_if_fail(BALSA_IS_MAILBOX_NODE(mbnode));
+
+    mbnode->list_inbox = !!list_inbox;
+}
+
+void
+balsa_mailbox_node_set_subscribed(BalsaMailboxNode * mbnode, guint subscribed)
+{
+    g_return_if_fail(BALSA_IS_MAILBOX_NODE(mbnode));
+
+    mbnode->subscribed = !!subscribed;
+}
+
+void
+balsa_mailbox_node_set_scanned(BalsaMailboxNode * mbnode, guint scanned)
+{
+    g_return_if_fail(BALSA_IS_MAILBOX_NODE(mbnode));
+
+    mbnode->scanned = !!scanned;
+}
+
+/*
+ * Getters
+ */
+
+LibBalsaMailbox *
+balsa_mailbox_node_get_mailbox(BalsaMailboxNode * mbnode)
+{
+    g_return_val_if_fail(BALSA_IS_MAILBOX_NODE(mbnode), NULL);
+
+    return mbnode->mailbox;
+}
+
+const gchar *
+balsa_mailbox_node_get_name(BalsaMailboxNode * mbnode)
+{
+    g_return_val_if_fail(BALSA_IS_MAILBOX_NODE(mbnode), NULL);
+
+    return mbnode->name;
+}
+
+const gchar *
+balsa_mailbox_node_get_config_prefix(BalsaMailboxNode * mbnode)
+{
+    g_return_val_if_fail(BALSA_IS_MAILBOX_NODE(mbnode), NULL);
+
+    return mbnode->config_prefix;
+}
+
+time_t
+balsa_mailbox_node_get_last_use_time(BalsaMailboxNode * mbnode)
+{
+    g_return_val_if_fail(BALSA_IS_MAILBOX_NODE(mbnode), 0);
+
+    return mbnode->last_use;
+}
+
+LibBalsaServer *
+balsa_mailbox_node_get_server(BalsaMailboxNode * mbnode)
+{
+    g_return_val_if_fail(BALSA_IS_MAILBOX_NODE(mbnode), NULL);
+
+    return mbnode->server;
+}
+
+BalsaMailboxNodeStyle
+balsa_mailbox_node_get_style(BalsaMailboxNode * mbnode)
+{
+    g_return_val_if_fail(BALSA_IS_MAILBOX_NODE(mbnode), 0);
+
+    return mbnode->style;
+}
+
+guint
+balsa_mailbox_node_get_subscribed(BalsaMailboxNode * mbnode)
+{
+    g_return_val_if_fail(BALSA_IS_MAILBOX_NODE(mbnode), 0);
+
+    return mbnode->subscribed;
+}
+
+guint
+balsa_mailbox_node_get_scanned(BalsaMailboxNode * mbnode)
+{
+    g_return_val_if_fail(BALSA_IS_MAILBOX_NODE(mbnode), FALSE);
+
+    return mbnode->scanned;
+}
+
+guint
+balsa_mailbox_node_get_list_inbox(BalsaMailboxNode * mbnode)
+{
+    g_return_val_if_fail(BALSA_IS_MAILBOX_NODE(mbnode), 0);
+
+    return mbnode->list_inbox;
+}
+
+gint
+balsa_mailbox_node_get_delim(BalsaMailboxNode * mbnode)
+{
+    g_return_val_if_fail(BALSA_IS_MAILBOX_NODE(mbnode), 0);
+
+    return mbnode->delim;
+}
+
+const gchar *
+balsa_mailbox_node_get_dir(BalsaMailboxNode * mbnode)
+{
+    g_return_val_if_fail(BALSA_IS_MAILBOX_NODE(mbnode), NULL);
+
+    return mbnode->dir;
+}
+
+BalsaMailboxNode *
+balsa_mailbox_node_get_parent(BalsaMailboxNode * mbnode)
+{
+    g_return_val_if_fail(BALSA_IS_MAILBOX_NODE(mbnode), NULL);
+
+    return mbnode->parent;
+}
diff --git a/src/mailbox-node.h b/src/mailbox-node.h
index f82790146..0385d0fc7 100644
--- a/src/mailbox-node.h
+++ b/src/mailbox-node.h
@@ -23,21 +23,14 @@
 #include <gtk/gtk.h>
 #include "libbalsa.h"
 
-#define BALSA_TYPE_MAILBOX_NODE          (balsa_mailbox_node_get_type ())
-#define BALSA_MAILBOX_NODE(obj) \
-    G_TYPE_CHECK_INSTANCE_CAST(obj, BALSA_TYPE_MAILBOX_NODE, \
-                                BalsaMailboxNode)
-#define BALSA_MAILBOX_NODE_CLASS(klass) \
-    G_TYPE_CHECK_CLASS_CAST(klass, BALSA_TYPE_MAILBOX_NODE, \
-                             BalsaMailboxNodeClass)
-#define BALSA_IS_MAILBOX_NODE(obj) \
-    G_TYPE_CHECK_INSTANCE_TYPE(obj, BALSA_TYPE_MAILBOX_NODE)
-#define BALSA_IS_MAILBOX_NODE_CLASS(klass) \
-    G_TYPE_CHECK_CLASS_TYPE(klass, BALSA_TYPE_MAILBOX_NODE)
-    
-typedef struct _BalsaMailboxNode BalsaMailboxNode;
-typedef struct _BalsaMailboxNodeClass BalsaMailboxNodeClass;
+#define BALSA_TYPE_MAILBOX_NODE (balsa_mailbox_node_get_type ())
 
+G_DECLARE_FINAL_TYPE(BalsaMailboxNode,
+                     balsa_mailbox_node,
+                     BALSA,
+                     MAILBOX_NODE,
+                     GObject)
+    
 /* BalsaMailboxNodeStyle 
  * used to store the style of mailbox entry in the mailbox tree.
  * Currently only MBNODE_STYLE_NEW_MAIL is really used, but
@@ -58,35 +51,6 @@ typedef enum {
     MBNODE_STYLE_UNREAD_CHILD = 1 << 4
 } BalsaMailboxNodeStyle;
 
-struct _BalsaMailboxNode {
-    GObject object;
-    BalsaMailboxNode *parent; /* NULL for root-level folders & mailboxes */
-    LibBalsaMailbox *mailbox; /* != NULL for leaves only */
-    gchar *name;       /* used for folders, i.e. when mailbox == NULL */
-    time_t last_use;   /* for closing least recently used mailboxes */
-    BalsaMailboxNodeStyle style;
-    /* folder data */
-    gchar* config_prefix;
-    gchar* dir;      
-    LibBalsaServer * server; /* Used only by remote; is referenced */
-    char delim; /* IMAP delimiter so that we do not need to check it
-                * too often. */
-
-    unsigned subscribed:1;     /* Used only by remote */
-    unsigned list_inbox:1;     /* Used only by remote */
-    unsigned scanned:1;        /* IMAP flag */
-};
-
-struct _BalsaMailboxNodeClass {
-    GObjectClass parent_class;
-    void (*save_config) (BalsaMailboxNode * mn, const gchar * prefix);
-    void (*load_config) (BalsaMailboxNode * mn, const gchar * prefix);
-    GtkWidget* (*show_prop_dialog) (BalsaMailboxNode * mn);
-    void (*append_subtree) (BalsaMailboxNode * mn);
-};
-
-GType balsa_mailbox_node_get_type(void);
-
 BalsaMailboxNode *balsa_mailbox_node_new(void);
 BalsaMailboxNode *balsa_mailbox_node_new_from_mailbox(LibBalsaMailbox *m);
 BalsaMailboxNode *balsa_mailbox_node_new_from_dir(const gchar* dir);
@@ -113,4 +77,35 @@ void balsa_mailbox_node_scan_children(BalsaMailboxNode * mbnode);
 /* return if the passed node resides on a remote IMAP server */
 gboolean balsa_mailbox_node_is_imap(const BalsaMailboxNode *mbnode);
 
+/*
+ * Setters
+ */
+void balsa_mailbox_node_set_dir(BalsaMailboxNode * mbnode, const gchar * dir);
+void balsa_mailbox_node_set_name(BalsaMailboxNode * mbnode, const gchar * name);
+void balsa_mailbox_node_set_config_prefix(BalsaMailboxNode * mbnode, const gchar * config_prefix);
+void balsa_mailbox_node_set_last_use_time(BalsaMailboxNode * mbnode);
+void balsa_mailbox_node_change_style(BalsaMailboxNode * mbnode,
+                                     BalsaMailboxNodeStyle set,
+                                     BalsaMailboxNodeStyle clear);
+void balsa_mailbox_node_set_subscribed(BalsaMailboxNode * mbnode, guint subscribed);
+void balsa_mailbox_node_set_scanned(BalsaMailboxNode * mbnode, guint scanned);
+void balsa_mailbox_node_set_list_inbox(BalsaMailboxNode * mbnode, guint list_inbox);
+
+/*
+ * Getters
+ */
+BalsaMailboxNode * balsa_mailbox_node_get_parent(BalsaMailboxNode * mbnode);
+LibBalsaMailbox * balsa_mailbox_node_get_mailbox(BalsaMailboxNode * mbnode);
+LibBalsaServer * balsa_mailbox_node_get_server(BalsaMailboxNode * mbnode);
+const gchar * balsa_mailbox_node_get_dir(BalsaMailboxNode * mbnode);
+const gchar * balsa_mailbox_node_get_name(BalsaMailboxNode * mbnode);
+const gchar * balsa_mailbox_node_get_config_prefix(BalsaMailboxNode * mbnode);
+time_t balsa_mailbox_node_get_last_use_time(BalsaMailboxNode * mbnode);
+BalsaMailboxNodeStyle balsa_mailbox_node_get_style(BalsaMailboxNode * mbnode);
+guint balsa_mailbox_node_get_subscribed(BalsaMailboxNode * mbnode);
+guint balsa_mailbox_node_get_scanned(BalsaMailboxNode * mbnode);
+guint balsa_mailbox_node_get_list_inbox(BalsaMailboxNode * mbnode);
+gint balsa_mailbox_node_get_delim(BalsaMailboxNode * mbnode);
+
+
 #endif
diff --git a/src/main-window.c b/src/main-window.c
index 946891454..e7dfb7a0c 100644
--- a/src/main-window.c
+++ b/src/main-window.c
@@ -2405,7 +2405,7 @@ bw_enable_mailbox_menus(BalsaWindow * window, BalsaIndex * index)
     enable = (index != NULL);
     if (enable) {
         mbnode = balsa_index_get_mailbox_node(index);
-        mailbox = mbnode->mailbox;
+        mailbox = balsa_mailbox_node_get_mailbox(mbnode);
     }
     bw_action_set_enabled(window, "mailbox-expunge",
     /* cppcheck-suppress nullPointer */
@@ -2737,7 +2737,7 @@ bw_notebook_label_new(BalsaMailboxNode * mbnode)
 
     box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
 
-    lab = gtk_label_new(libbalsa_mailbox_get_name(mbnode->mailbox));
+    lab = gtk_label_new(libbalsa_mailbox_get_name(balsa_mailbox_node_get_mailbox(mbnode)));
     gtk_widget_set_name(lab, "balsa-notebook-tab-label");
 
     /* Try to make text not bold: */
@@ -2756,8 +2756,8 @@ bw_notebook_label_new(BalsaMailboxNode * mbnode)
     g_object_unref(css_provider);
 
     bw_notebook_label_style(GTK_LABEL(lab),
-                            libbalsa_mailbox_get_unread(mbnode->mailbox) > 0);
-    g_signal_connect_object(mbnode->mailbox, "changed",
+                            libbalsa_mailbox_get_unread(balsa_mailbox_node_get_mailbox(mbnode)) > 0);
+    g_signal_connect_object(balsa_mailbox_node_get_mailbox(mbnode), "changed",
                             G_CALLBACK(bw_mailbox_changed), lab, 0);
     gtk_box_pack_start(GTK_BOX(box), lab, TRUE, TRUE, 0);
 
@@ -2782,7 +2782,7 @@ bw_notebook_label_new(BalsaMailboxNode * mbnode)
 
     gtk_widget_show_all(box);
 
-    gtk_widget_set_tooltip_text(box, libbalsa_mailbox_get_url(mbnode->mailbox));
+    gtk_widget_set_tooltip_text(box, libbalsa_mailbox_get_url(balsa_mailbox_node_get_mailbox(mbnode)));
     return box;
 }
 
@@ -2805,7 +2805,7 @@ bw_real_open_mbnode_idle_cb(BalsaWindowRealOpenMbnodeInfo * info)
     BalsaIndex        *index   = info->index;
     BalsaMailboxNode  *mbnode  = info->mbnode;
     BalsaWindow       *window  = info->window;
-    LibBalsaMailbox   *mailbox = mbnode->mailbox;
+    LibBalsaMailbox   *mailbox = balsa_mailbox_node_get_mailbox(mbnode);
     GtkWidget         *label;
     GtkWidget         *scroll;
     gint               page_num;
@@ -2884,7 +2884,7 @@ bw_real_open_mbnode_thread(BalsaWindowRealOpenMbnodeInfo * info)
 {
     static GMutex open_lock;
     gint try_cnt;
-    LibBalsaMailbox *mailbox = info->mbnode->mailbox;
+    LibBalsaMailbox *mailbox = balsa_mailbox_node_get_mailbox(info->mbnode);
     GError *err = NULL;
     gboolean successp;
 
@@ -2948,7 +2948,7 @@ balsa_window_real_open_mbnode(BalsaWindow * window,
     GThread *open_thread;
     BalsaWindowRealOpenMbnodeInfo *info;
 
-    if (bw_is_open_mailbox(mailbox = mbnode->mailbox))
+    if (bw_is_open_mailbox(mailbox = balsa_mailbox_node_get_mailbox(mbnode)))
         return;
 
     index = BALSA_INDEX(balsa_index_new());
@@ -3004,13 +3004,13 @@ balsa_window_real_close_mbnode(BalsaWindow * window,
     gint i;
     LibBalsaMailbox **mailbox;
 
-    g_return_if_fail(mbnode->mailbox);
+    g_return_if_fail(balsa_mailbox_node_get_mailbox(mbnode));
 
-    i = balsa_find_notebook_page_num(mbnode->mailbox);
+    i = balsa_find_notebook_page_num(balsa_mailbox_node_get_mailbox(mbnode));
 
     if (i != -1) {
         gtk_notebook_remove_page(GTK_NOTEBOOK(window->notebook), i);
-        bw_unregister_open_mailbox(mbnode->mailbox);
+        bw_unregister_open_mailbox(balsa_mailbox_node_get_mailbox(mbnode));
 
         /* If this is the last notebook page clear the message preview
            and the status bar */
@@ -3242,7 +3242,7 @@ bw_check_mailbox_list(struct check_messages_thread_info *info, GList *mailbox_li
     }
 
     for ( ; mailbox_list; mailbox_list = mailbox_list->next) {
-        LibBalsaMailbox *mailbox = BALSA_MAILBOX_NODE(mailbox_list->data)->mailbox;
+        LibBalsaMailbox *mailbox = balsa_mailbox_node_get_mailbox(mailbox_list->data);
         LibBalsaMailboxPOP3 *pop3 = LIBBALSA_MAILBOX_POP3(mailbox);
         bw_pop_mbox_t *bw_pop_mbox;
 
@@ -3276,9 +3276,9 @@ bw_add_mbox_to_checklist(GtkTreeModel * model, GtkTreePath * path,
     gtk_tree_model_get(model, iter, 0, &mbnode, -1);
     g_return_val_if_fail(mbnode, FALSE);
 
-    if ((mailbox = mbnode->mailbox)) { /* mailbox, not a folder */
+    if ((mailbox = balsa_mailbox_node_get_mailbox(mbnode))) {  /* mailbox, not a folder */
        if (!LIBBALSA_IS_MAILBOX_IMAP(mailbox) ||
-           bw_imap_check_test(mbnode->dir ? mbnode->dir :
+           bw_imap_check_test(balsa_mailbox_node_get_dir(mbnode) ? balsa_mailbox_node_get_dir(mbnode) :
                            libbalsa_mailbox_imap_get_path
                            (LIBBALSA_MAILBOX_IMAP(mailbox))))
            *list = g_slist_prepend(*list, g_object_ref(mailbox));
@@ -3589,9 +3589,9 @@ mw_mbox_change_connection_status(GtkTreeModel * model, GtkTreePath * path,
     gtk_tree_model_get(model, iter, 0, &mbnode, -1);
     g_return_val_if_fail(mbnode, FALSE);
 
-    if ((mailbox = mbnode->mailbox)) {  /* mailbox, not a folder */
+    if ((mailbox = balsa_mailbox_node_get_mailbox(mbnode))) {  /* mailbox, not a folder */
         if (LIBBALSA_IS_MAILBOX_IMAP(mailbox) &&
-            bw_imap_check_test(mbnode->dir ? mbnode->dir :
+            bw_imap_check_test(balsa_mailbox_node_get_dir(mbnode) ? balsa_mailbox_node_get_dir(mbnode) :
                                libbalsa_mailbox_imap_get_path(LIBBALSA_MAILBOX_IMAP(mailbox)))) {
             libbalsa_mailbox_test_can_reach(g_object_ref(mailbox),
                                             mw_mbox_can_reach_cb, NULL);
@@ -3645,7 +3645,7 @@ bw_change_connection_status_idle(gpointer user_data)
         return FALSE;
     if ((mbnode = balsa_app.inbox_input->data) == NULL)
         return FALSE;
-    if ((mailbox = mbnode->mailbox) == NULL)
+    if ((mailbox = balsa_mailbox_node_get_mailbox(mbnode)) == NULL)
         return FALSE;
 
     libbalsa_mailbox_test_can_reach(mailbox, bw_change_connection_status_can_reach_cb,
@@ -4652,7 +4652,7 @@ update_view_menu(BalsaWindow * window)
 void
 balsa_window_update_tab(BalsaMailboxNode * mbnode)
 {
-    gint i = balsa_find_notebook_page_num(mbnode->mailbox);
+    gint i = balsa_find_notebook_page_num(balsa_mailbox_node_get_mailbox(mbnode));
     if (i != -1) {
        GtkWidget *page =
            gtk_notebook_get_nth_page(GTK_NOTEBOOK(balsa_app.notebook), i);
diff --git a/src/main.c b/src/main.c
index e0029ee25..e8fd12fcc 100644
--- a/src/main.c
+++ b/src/main.c
@@ -332,7 +332,8 @@ periodic_expunge_cb(void)
     GSList *list = NULL, *l;
 
     /* should we enforce expunging now and then? Perhaps not... */
-    if(!balsa_app.expunge_auto) return TRUE;
+    if (!balsa_app.expunge_auto)
+        return TRUE;
 
     libbalsa_information(LIBBALSA_INFORMATION_DEBUG,
                          _("Compressing mail folders…"));
@@ -340,13 +341,15 @@ periodic_expunge_cb(void)
                           (GtkTreeModelForeachFunc)mbnode_expunge_func,
                           &list);
 
-    for (l = list; l; l = l->next) {
+    for (l = list; l != NULL; l = l->next) {
         BalsaMailboxNode *mbnode = l->data;
-        if (mbnode->mailbox && libbalsa_mailbox_is_open(mbnode->mailbox)
-            && !libbalsa_mailbox_get_readonly(mbnode->mailbox)) {
+        LibBalsaMailbox *mailbox = balsa_mailbox_node_get_mailbox(mbnode);
+
+        if (mailbox != NULL && libbalsa_mailbox_is_open(mailbox) &&
+            !libbalsa_mailbox_get_readonly(mailbox)) {
             time_t tm = time(NULL);
-            if (tm-mbnode->last_use > balsa_app.expunge_timeout)
-                libbalsa_mailbox_sync_storage(mbnode->mailbox, TRUE);
+            if (tm - balsa_mailbox_node_get_last_use_time(mbnode) > balsa_app.expunge_timeout)
+                libbalsa_mailbox_sync_storage(mailbox, TRUE);
         }
         g_object_unref(mbnode);
     }
diff --git a/src/pref-manager.c b/src/pref-manager.c
index 0fdb525e9..de8f9f144 100644
--- a/src/pref-manager.c
+++ b/src/pref-manager.c
@@ -981,18 +981,18 @@ add_other_server(BalsaMailboxNode * mbnode, GtkTreeModel * model)
     const gchar *name = NULL;
     gboolean append = FALSE;
 
-    if (mbnode) {
-        LibBalsaMailbox *mailbox = mbnode->mailbox;
-        if (mailbox) {
+    if (mbnode != NULL) {
+        LibBalsaMailbox *mailbox = balsa_mailbox_node_get_mailbox(mbnode);
+        if (mailbox != NULL) {
             if (LIBBALSA_IS_MAILBOX_IMAP(mailbox)) {
                 protocol = "IMAP";
                 name = libbalsa_mailbox_get_name(mailbox);
                 append = TRUE;
             }
         } else
-            if (LIBBALSA_IS_IMAP_SERVER(mbnode->server)) {
+            if (LIBBALSA_IS_IMAP_SERVER(balsa_mailbox_node_get_server(mbnode))) {
             protocol = "IMAP";
-            name = mbnode->name;
+            name = balsa_mailbox_node_get_name(mbnode);
             append = TRUE;
         }
         if (append) {
@@ -1737,7 +1737,7 @@ server_del_cb(GtkTreeView * tree_view)
     gtk_tree_model_get(model, &iter, MS_DATA_COLUMN, &mbnode, -1);
     g_return_if_fail(mbnode);
 
-    if (mbnode->mailbox)
+    if (balsa_mailbox_node_get_mailbox(mbnode) != NULL)
        mailbox_conf_delete(mbnode);
     else
        folder_conf_delete(mbnode);
@@ -3582,11 +3582,15 @@ update_mail_servers(void)
 
     gtk_list_store_clear(GTK_LIST_STORE(model));
     for (list = balsa_app.inbox_input; list; list = list->next) {
+        LibBalsaMailbox *mailbox;
+
         if (!(mbnode = list->data))
             continue;
-        if (LIBBALSA_IS_MAILBOX_POP3(mbnode->mailbox))
+
+        mailbox = balsa_mailbox_node_get_mailbox(mbnode);
+        if (LIBBALSA_IS_MAILBOX_POP3(mailbox))
             protocol = "POP3";
-        else if (LIBBALSA_IS_MAILBOX_IMAP(mbnode->mailbox))
+        else if (LIBBALSA_IS_MAILBOX_IMAP(mailbox))
             protocol = "IMAP";
         else
             protocol = _("Unknown");
@@ -3594,7 +3598,8 @@ update_mail_servers(void)
         gtk_list_store_append(GTK_LIST_STORE(model), &iter);
         gtk_list_store_set(GTK_LIST_STORE(model), &iter,
                            MS_PROT_COLUMN, protocol,
-                           MS_NAME_COLUMN, libbalsa_mailbox_get_name(mbnode->mailbox),
+                           MS_NAME_COLUMN,
+                           libbalsa_mailbox_get_name(mailbox),
                            MS_DATA_COLUMN, mbnode, -1);
     }
     /*
diff --git a/src/save-restore.c b/src/save-restore.c
index 6ff1c8d53..9775f2244 100644
--- a/src/save-restore.c
+++ b/src/save-restore.c
@@ -69,11 +69,6 @@ static void config_filters_load(void);
 
 static inline gboolean is_special_name(const gchar *name);
 
-#define folder_section_path(mn) \
-    BALSA_MAILBOX_NODE(mn)->config_prefix ? \
-    g_strdup(BALSA_MAILBOX_NODE(mn)->config_prefix) : \
-    config_get_unused_group(FOLDER_SECTION_PREFIX)
-
 static gchar *
 mailbox_section_path(LibBalsaMailbox * mailbox)
 {
@@ -85,6 +80,17 @@ mailbox_section_path(LibBalsaMailbox * mailbox)
         config_get_unused_group(MAILBOX_SECTION_PREFIX);
 }
 
+static gchar *
+folder_section_path(BalsaMailboxNode * mbnode)
+{
+    const gchar *config_prefix =
+        balsa_mailbox_node_get_config_prefix(mbnode);
+
+    return config_prefix != NULL ?
+        g_strdup(config_prefix) :
+        config_get_unused_group(FOLDER_SECTION_PREFIX);
+}
+
 static gchar *
 address_book_section_path(LibBalsaAddressBook *address_book)
 {
@@ -127,26 +133,32 @@ migrate_imap_mailboxes(const gchar *key, const gchar *value, gpointer data)
                libbalsa_conf_pop_group();
                mbnode = balsa_mailbox_node_new_from_config(key);
            if (mbnode != NULL) {
-                LibBalsaServer *server = mbnode->server;
+                LibBalsaServer *server = balsa_mailbox_node_get_server(mbnode);
                gchar *folder_key;
                gchar *oldname;
 
                /* do not add the same folder multiple times */
                folder_key = g_strconcat(libbalsa_server_get_user(server), "@",
                                          libbalsa_server_get_host(server), NULL);
-               oldname = g_strdup(mbnode->name);
+               oldname = g_strdup(balsa_mailbox_node_get_name(mbnode));
                if (g_hash_table_contains(migrated, folder_key)) {
                        g_object_unref(mbnode);
                        g_free(folder_key);
                } else {
+                        gchar *tmp;
+
                        g_hash_table_add(migrated, folder_key);
-                       g_free(mbnode->name);
-                       mbnode->name = g_strdup(libbalsa_server_get_host(server));
+                       balsa_mailbox_node_set_name(mbnode, libbalsa_server_get_host(server));
                        balsa_mblist_mailbox_node_append(NULL, mbnode);
 
-                       g_free(mbnode->config_prefix);
-                       mbnode->config_prefix = config_get_unused_group(FOLDER_SECTION_PREFIX);
-                       g_signal_connect_swapped(mbnode->server, "config-changed", 
G_CALLBACK(config_folder_update), mbnode);
+                       tmp =  config_get_unused_group(FOLDER_SECTION_PREFIX);
+                       balsa_mailbox_node_set_config_prefix(mbnode, tmp);
+                        g_free(tmp);
+
+                       g_signal_connect_swapped(balsa_mailbox_node_get_server(mbnode),
+                                                 "config-changed",
+                                                 G_CALLBACK(config_folder_update),
+                                                 mbnode);
                }
 
                if (!is_special_name(value)) {
@@ -412,7 +424,7 @@ config_mailbox_delete(LibBalsaMailbox * mailbox)
 }                              /* config_mailbox_delete */
 
 gint
-config_folder_delete(const BalsaMailboxNode * mbnode)
+config_folder_delete(BalsaMailboxNode * mbnode)
 {
     gchar *tmp;                        /* the key in the mailbox section name */
     gint res;
@@ -537,7 +549,8 @@ config_folder_init(const gchar * prefix)
     g_return_val_if_fail(prefix != NULL, FALSE);
 
     if( (folder = balsa_mailbox_node_new_from_config(prefix)) ) {
-       g_signal_connect_swapped(folder->server, "config-changed",
+       g_signal_connect_swapped(balsa_mailbox_node_get_server(folder),
+                                 "config-changed",
                                  G_CALLBACK(config_folder_update),
                                 folder);
        balsa_mblist_mailbox_node_append(NULL, folder);
diff --git a/src/save-restore.h b/src/save-restore.h
index 1fa9497c7..55112ceb7 100644
--- a/src/save-restore.h
+++ b/src/save-restore.h
@@ -51,7 +51,7 @@ gint config_mailbox_delete(LibBalsaMailbox * mailbox);
 gint config_mailbox_update(LibBalsaMailbox * mailbox);
 
 gint config_folder_add(BalsaMailboxNode * mbnode, const char *key_arg);
-gint config_folder_delete(const BalsaMailboxNode * mbnode);
+gint config_folder_delete(BalsaMailboxNode * mbnode);
 gint config_folder_update(BalsaMailboxNode * mbnode);
 
 void config_address_book_save(LibBalsaAddressBook * ab);


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