diff -Nur --exclude=CVS --exclude=gtkhtml balsa-cvs/libbalsa/folder-scanners.c balsa-imap-multiple4/libbalsa/folder-scanners.c
--- balsa-cvs/libbalsa/folder-scanners.c	Sat Oct 13 16:24:03 2001
+++ balsa-imap-multiple4/libbalsa/folder-scanners.c	Tue Oct 16 09:15:35 2001
@@ -137,8 +137,52 @@
 /* ---------------------------------------------------------------------
  * IMAP folder scanner functions 
  * --------------------------------------------------------------------- */
-void imap_add_folder (char delim, char *folder, int noselect, int noinferiors,
-		      struct browser_state *state, short isparent);
+struct imap_folder {
+    char delim;
+    char *folder;
+    int  noselect;
+    int  noinferiors;
+    int  synthetic;
+};
+
+static struct imap_folder *
+imap_folder_new(char delim, char *folder, int noselect, int noinferiors,
+                int synthetic)
+{
+    struct imap_folder *f = g_malloc(sizeof(struct imap_folder));
+    f->delim = delim;
+    f->folder = g_strdup(folder);
+    f->noselect = noselect;
+    f->noinferiors = noinferiors;
+    f->synthetic = synthetic;
+    return f;
+}
+
+static void
+imap_folder_free(struct imap_folder *f)
+{
+    g_free(f->folder);
+    g_free(f);
+}
+
+static  gint
+imap_folder_compare(struct imap_folder *f0, struct imap_folder *f1)
+{
+    return strcmp(f0->folder, f1->folder);
+}
+
+static gint
+imap_folder_find(struct imap_folder *f, const gchar * name)
+{
+    return strcmp(f->folder, name);
+}
+
+void imap_add_folder(char delim, char *folder, int noselect,
+                     int noinferiors, struct browser_state *state,
+                     short isparent, int synthetic, int check_flags_only);
+static void imap_add_folder_real(struct imap_folder *f,
+                             struct browser_state *state);
+
 void
 libbalsa_scanner_imap_dir(GNode *rnode, LibBalsaServer * server, 
 			  const gchar* path, gboolean subscribed, int depth,
@@ -146,7 +190,6 @@
 			  ImapHandler mailbox_handler)
 {
     gchar* imap_path;
-    GList* list = NULL, *el;
     struct browser_state state;
     int i;
 
@@ -156,6 +199,7 @@
     state.rnode = rnode;
     state.mailbox_handler = (void(*)())mailbox_handler;
     state.folder_handler = (void(*)())folder_handler;
+    state.folder_list = (struct imap_folder *) NULL;
     if(!FileMask.rx) { /* allocate it once, on the first run */
        FileMask.rx = (regex_t *) safe_malloc (sizeof (regex_t));
        if( (i=REGCOMP(FileMask.rx,"!^\\.[^.]",0)) != 0) {
@@ -175,73 +219,114 @@
 	set_option(OPTIMAPLSUB);
     else
 	unset_option(OPTIMAPLSUB);
-    state.subfolders = g_list_append(NULL, g_strdup(path));
+    state.subfolders = NULL; /*g_list_append(NULL, g_strdup(path)); */
     state.folder = NULL;
 
-    for(i=0; state.subfolders && i<depth; i++) {
-	list = state.subfolders;
-	state.subfolders = NULL;
-	printf("Deph: %i -------------------------------------------\n", i);
-	for(el= g_list_first(list); el; el = g_list_next(el)) {
-	    if(*(char*)el->data)
-		imap_path = g_strdup_printf("imap%s://%s:%i/%s/", 
+    if(*path)
+	imap_path = g_strdup_printf("imap%s://%s:%i/%s/", 
 #ifdef USE_SSL
-					    server->use_ssl ? "s" : "",
+				    server->use_ssl ? "s" : "",
 #else
-					    "",
+				    "",
 #endif
-					    server->host, server->port, 
-					    (char*)el->data);
-	    else 
-		imap_path = g_strdup_printf("imap%s://%s:%i/", 
+				    server->host, server->port, 
+				    path);
+    else 
+	imap_path = g_strdup_printf("imap%s://%s:%i/", 
 #ifdef USE_SSL
-					    server->use_ssl ? "s" : "",
+				    server->use_ssl ? "s" : "",
 #else
-					    "",
+				    "",
 #endif
-					    server->host, server->port);
-	    FREE(&state.folder);
-	    imap_browse ((char*)imap_path,  &state);
-	    g_free(imap_path);
-	}
-	g_list_foreach(list, (GFunc)g_free, NULL);
-	g_list_free(list); 
-    }
+				    server->host, server->port);
+    imap_browse ((char*)imap_path,  &state);
+    g_free(imap_path);
     g_list_foreach((GList*)state.subfolders, (GFunc)g_free, NULL);
     g_list_free((GList*)state.subfolders);
+    
+    state.folder_list =
+        g_list_sort(state.folder_list,
+                    (GCompareFunc) imap_folder_compare);
+    g_list_foreach((GList *) state.folder_list, (GFunc) imap_add_folder_real,
+                   &state);
+    g_list_foreach((GList *) state.folder_list, (GFunc) imap_folder_free, NULL);
+    g_list_free((GList *) state.folder_list);
+
     state_free (&state);
     libbalsa_unlock_mutt();
-    
 }
 
 /* this function ovverrides mutt's one. */
-void imap_add_folder (char delim, char *folder, int noselect,
-  int noinferiors, struct browser_state *state, short isparent)
+
+void
+imap_add_folder(char delim, char *folder, int noselect,
+                int noinferiors, struct browser_state *state,
+                short isparent, int synthetic, int check_flags_only)
+{
+    GList *list;
+    struct imap_folder *f;
+    if (isparent)
+        return;
+    imap_unmunge_mbox_name(folder);
+    list = g_list_find_custom(state->folder_list, folder,
+                              (GCompareFunc) imap_folder_find);
+    if (list == NULL) {
+        /* it's a new folder name */
+        if (!check_flags_only)
+            state->folder_list =
+                g_list_append(state->folder_list,
+                              (gpointer) imap_folder_new(delim, folder,
+                                                         noselect,
+                                                         noinferiors,
+                                                         synthetic));
+    } else {
+        f = list->data;
+        if (f->synthetic) {
+            /* found a synthetic node */
+            if (!(synthetic || check_flags_only)) {
+                /* the new node is real, so set the flags */
+                f->noselect = noselect;
+                f->noinferiors = noinferiors;
+                f->synthetic = FALSE;
+            }
+        } else {
+            /* only case left: we found a real node */
+            if (!synthetic) {
+                if (noselect)
+                    f->noselect = TRUE;
+                if (noinferiors)
+                    f->noinferiors = TRUE;
+            }
+        }
+    }
+}
+
+static void
+imap_add_folder_real(struct imap_folder *f, struct browser_state *state)
 {
     int isFolder = 0;
     int isMailbox = 0;
 
-    imap_unmunge_mbox_name (folder);
     /* printf("imap_add_folder. delim: '%c', folder: '%s', noselect: %d\n"
 	   "noinferiors: %d, isparent: %d\n", delim, folder, noselect,
 	   noinferiors, isparent);  */
-    if(isparent) return;
-    if(!noselect) {
-	printf("ADDING MAILBOX %s\n", folder);
+    if(!(f->noselect || f->synthetic)) {
+	printf("ADDING MAILBOX %s\n", f->folder);
 	++isMailbox;
     }
     /* this extra check is needed for subscribed folder handling. 
 	   Read RFC when iin doubt. */
-    if(!g_list_find_custom(state->subfolders, folder,
-			   (GCompareFunc)strcmp)) {
-	printf("ADDING FOLDER  %s\n", folder);
+    if(!f->noinferiors
+       && !g_list_find_custom(state->subfolders, f->folder,
+                              (GCompareFunc)strcmp)) {
+	printf("ADDING FOLDER  %s\n", f->folder);
 	    
 	state->subfolders = g_list_append(state->subfolders,
-					  g_strdup(folder));
+					  g_strdup(f->folder));
 	++isFolder;
     }
     if (isMailbox)
-	state->mailbox_handler(state->rnode, folder, delim);
+	state->mailbox_handler(state->rnode, f->folder, f->delim);
     else if (isFolder)
-	state->folder_handler(state->rnode, folder, delim);
+	state->folder_handler(state->rnode, f->folder, f->delim);
 }
diff -Nur --exclude=CVS --exclude=gtkhtml balsa-cvs/libmutt/browser.h balsa-imap-multiple4/libmutt/browser.h
--- balsa-cvs/libmutt/browser.h	Tue Aug 21 11:02:12 2001
+++ balsa-imap-multiple4/libmutt/browser.h	Mon Oct 15 10:59:44 2001
@@ -51,6 +51,11 @@
   int noselect : 1;
   int marked : 1;
   int unmarked : 1;
+/* #ifdef LIBMUTT multiple */
+  LIST* seq_list;
+  int   pending;
+  void  *folder_list;
+/* #endif LIBMUTT multiple */
   /*BALSA data begin */
   void * rnode;        /* points to a GNode */
   void * server;       /* points to a LibBalsaServer */
diff -Nur --exclude=CVS --exclude=gtkhtml balsa-cvs/libmutt/imap/browse.c balsa-imap-multiple4/libmutt/imap/browse.c
--- balsa-cvs/libmutt/imap/browse.c	Tue Aug 21 11:02:12 2001
+++ balsa-imap-multiple4/libmutt/imap/browse.c	Tue Oct 16 09:37:54 2001
@@ -35,18 +35,32 @@
   state->entrymax = 256;
   state->entry = (struct folder_file *) 
     safe_malloc (sizeof (struct folder_file) * state->entrymax);
+#ifdef LIBMUTT /* multiple */
+  state->seq_list = mutt_new_list();
+  state->pending  = 0;
+#endif /* LIBMUTT multiple */
 }
 
 void state_free (struct browser_state *state)
 {
   safe_free((void**)&state->entry);
   safe_free((void**)&state->folder);
+#ifdef LIBMUTT /* multiple */
+  mutt_free_list(&state->seq_list);
+#endif /* LIBMUTT multiple */
 }
 /* #endif */
 
 /* -- forward declarations -- */
 static int browse_add_list_result (IMAP_DATA* idata, const char* cmd,
   struct browser_state* state, short isparent);
+#ifdef LIBMUTT /* multiple */
+static int browse_add_list_result_end (IMAP_DATA* idata,
+  struct browser_state* state, IMAP_NAMESPACE_INFO* nsi, int nns);
+void imap_add_folder (char delim, char *folder, int noselect,
+  int noinferiors, struct browser_state *state, short isparent, 
+  int synthetic, int check_flags_only);
+#endif /* LIBMUTT multiple */
 #ifndef LIBMUTT
 static void imap_add_folder (char delim, char *folder, int noselect,
   int noinferiors, struct browser_state *state, short isparent);
@@ -73,7 +87,11 @@
   int i;
   int nsup;
   char ctmp;
+#ifdef LIBMUTT /* multiple */
+  int nns = 0;
+#else
   int nns;
+#endif /* LIBMUTT multiple */
   char *cur_folder;
   short showparents = 0;
   int noselect;
@@ -96,7 +114,9 @@
     home_namespace = 1;
     mbox[0] = '\0';		/* Do not replace "" with "INBOX" here */
     mx.mbox = safe_strdup(ImapHomeNamespace);
+#ifndef LIBMUTT /* multiple */
     nns = 0;
+#endif /* LIBMUTT multiple */
     if (mutt_bit_isset(idata->capabilities,NAMESPACE))
     {
       mutt_message _("Getting namespaces...");
@@ -177,7 +197,11 @@
       if (showparents)
       {
 	dprint (3, (debugfile, "imap_init_browse: adding parent %s\n", mbox));
+#ifdef LIBMUTT /* multiple */
+	imap_add_folder (idata->delim, mbox, 1, 0, state, 1, 0, 0);
+#else
 	imap_add_folder (idata->delim, mbox, 1, 0, state, 1);
+#endif /* LIBMUTT multiple */
       }
 
       /* if our target isn't a folder, we are in our superior */
@@ -199,7 +223,11 @@
       /* folder may be "/" */
       snprintf (relpath, sizeof (relpath), "%c" , n < 0 ? '\0' : idata->delim);
       if (showparents)
+#ifdef LIBMUTT /* multiple */
+        imap_add_folder (idata->delim, relpath, 1, 0, state, 1, 0, 0); 
+#else
         imap_add_folder (idata->delim, relpath, 1, 0, state, 1); 
+#endif /* LIBMUTT multiple */
       if (!state->folder)
       {
         imap_qualify_path (buf, sizeof (buf), &mx, relpath);
@@ -224,16 +252,39 @@
     if (browse_add_list_result (idata, "LIST \"\" \"INBOX\"", state, 0))
       goto fail;
   }
+  
+#ifdef LIBMUTT /* multiple */
+  if (!home_namespace && mbox[0] != '\0')
+  {
+    /* uw-imap servers include "prefix." when asked to LIST "prefix.%",
+     * but cyrus servers don't. We'll ask for this response explicitly,
+     * and rely on later code to avoid duplicating that entry when we're
+     * talking to uw-imap */
+    int n = strlen(mx.mbox);
+    if (mx.mbox[--n] == idata->delim || mx.mbox[n] == '/')
+      mx.mbox[n] = '\0';
+    imap_quote_string (buf2, sizeof (buf2), mx.mbox);
+    snprintf (buf, sizeof (buf), "%s \"\" %s", list_cmd, buf2);
+    if (browse_add_list_result (idata, buf, state, 0))
+      goto fail;
+  }
+#endif /* LIBMUTT multiple */
 
   nsup = state->entrylen;
 
   dprint (3, (debugfile, "imap_browse: Quoting mailbox scan: %s -> ", mbox));
+#ifdef LIBMUTT /* multiple */
+  snprintf (buf, sizeof (buf), "%s%c", mbox, option(OPTIMAPLSUB) ? '*' : '%');
+#else
   snprintf (buf, sizeof (buf), "%s%%", mbox);
+#endif /* LIBMUTT multiple */
   imap_quote_string (buf2, sizeof (buf2), buf);
   dprint (3, (debugfile, "%s\n", buf2));
   snprintf (buf, sizeof (buf), "%s \"\" %s", list_cmd, buf2);
   if (browse_add_list_result (idata, buf, state, 0))
     goto fail;
+  if (browse_add_list_result_end(idata, state, nsi, nns) < 0)
+    goto fail;
 
   mutt_clear_error ();
 
@@ -243,13 +294,34 @@
   {				/* List additional namespaces */
     for (i = 0; i < nns; i++)
       if (nsi[i].listable && !nsi[i].home_namespace) {
+#ifdef LIBMUTT /* multiple */
+        char buf[LONG_STRING];
+
+        snprintf(buf, sizeof(buf), "%s \"\" \"%s%c%c\"",
+                 option(OPTIMAPLSUB) ? "LSUB" : "LIST", nsi[i].prefix,
+                 nsi[i].delim, option(OPTIMAPLSUB) ? '*' : '%');
+        browse_add_list_result(idata, buf, state, 0);
+#endif /* LIBMUTT multiple */
+
 	imap_add_folder(nsi[i].delim, nsi[i].prefix, nsi[i].noselect,
+#ifdef LIBMUTT /* multiple */
+			nsi[i].noinferiors, state, 0, 0, 0);
+#else
 			nsi[i].noinferiors, state, 0);
+#endif /* LIBMUTT multiple */
 	dprint (3, (debugfile, "imap_init_browse: adding namespace: %s\n",
 		    nsi[i].prefix));
       }
   }
 
+#ifdef LIBMUTT /* multiple */
+  /* wait for responses */
+  while (state->pending)
+    if (browse_add_list_result_end(idata, state, nsi, nns) < 0)
+      goto fail;
+
+  imap_cmd_finish (idata);
+#endif /* LIBMUTT multiple */
   FREE (&mx.mbox);
   return 0;
 
@@ -341,14 +413,57 @@
   return -1;
 }
 
+#ifdef LIBMUTT /* multiple */
+static LIST * is_in_list(const char * s, LIST * l, int offset, int len)
+{   
+  LIST *previous = l;
+
+  /* mutt_lists have a head node with NULL data, so we never match
+   * it, and we can start with l->next */
+  for (l = l->next; l; l = l->next)
+  {
+    if (l->data && !strncmp(s, l->data + offset, len))
+      return previous;
+    previous = l;
+  }
+  return NULL;
+}
+
+static int remove_from_list(const char * s, LIST * list)
+{
+  LIST *previous = is_in_list(s, list, 0, SEQLEN);
+  if (previous)
+  {
+    LIST *l = previous->next;
+    if (!imap_code(s))
+      printf("remove_from_list: command \"%s\"\n"
+             "        received response \"%s\"\n", l->data, s);
+    previous->next = l->next;
+    l->next = NULL;
+    /* mutt_free_list frees the data and the list node */
+    mutt_free_list(&l);
+    return 1;
+  }
+  return 0;
+}
+#endif /* LIBMUTT multiple */
 
 static int browse_add_list_result (IMAP_DATA* idata, const char* cmd,
   struct browser_state* state, short isparent)
 {
+#ifndef LIBMUTT /* multiple */
   char *name;
   int noselect;
   int noinferiors;
+#endif /* LIBMUTT multiple */
   IMAP_MBOX mx;
+#ifdef LIBMUTT /* multiple */
+  int outlen;
+  char *out;
+
+  if (isparent)
+    return 0;
+#endif /* LIBMUTT multiple */
 
   if (imap_parse_path (state->folder, &mx))
   {
@@ -357,8 +472,43 @@
     return -1;
   }
 
+#ifdef LIBMUTT /* multiple */
+  if (is_in_list(cmd, state->seq_list, SEQLEN + 1, strlen(cmd)))
+    return 0;
+#endif /* LIBMUTT multiple */
+
   imap_cmd_start (idata, cmd);
 
+#ifdef LIBMUTT /* multiple */
+  outlen = strlen (idata->cmd.seq) + strlen (cmd) + 4;
+  out = (char*) safe_malloc (outlen);
+  snprintf (out, outlen, "%s %s", idata->cmd.seq, cmd);
+  /* we'll handle tagged responses, so set a fake seq */
+  snprintf (idata->cmd.seq, sizeof (idata->cmd.seq), "zzzzz");
+  mutt_add_list(state->seq_list, out);
+  ++state->pending;
+  FREE(&out);
+
+  FREE (&mx.mbox);
+  return 0;
+}
+
+static int browse_add_list_result_end (IMAP_DATA* idata,
+  struct browser_state* state, IMAP_NAMESPACE_INFO* nsi, int nns)
+{
+  char *name;
+  int noselect;
+  int noinferiors;
+  IMAP_MBOX mx;
+
+  if (imap_parse_path (state->folder, &mx))
+  {
+    dprint (2, (debugfile,
+      "browse_add_list_result: current folder %s makes no sense\n", state->folder));
+    return -1;
+  }
+#endif /* LIBMUTT multiple */
+
   do 
   {
     if (imap_parse_list_response(idata, &name, &noselect, &noinferiors,
@@ -370,16 +520,98 @@
 
     if (name)
     {
+#ifdef LIBMUTT /* multiple */
+      int n = mutt_strlen(name);
+      int i;
+      /* strip quotes, if any */
+      imap_unquote_string(name);
+      /* trim trailing delim, if any */
+      if (name[--n] == idata->delim)
+        name[n] = '\0';
+      /* don't list any namespaces that we've already listed */
+      for (i = 0; i < nns; ++i)
+      {
+        if (nsi[i].listable && strcmp(name, nsi[i].prefix) == 0)
+          nsi[i].listable = 0;
+      }
+#else  /* LIBMUTT multiple */
       /* Let a parent folder never be selectable for navigation */
       if (isparent)
         noselect = 1;
       /* prune current folder from output */
+      /* if this was a LIST response and OPTIMAPLSUB is set, we're only
+       * checking flags, not creating new nodes */
       if (isparent || mutt_strncmp (name, mx.mbox, strlen (name)))
         imap_add_folder (idata->delim, name, noselect, noinferiors, state,
           isparent);
+#endif /* LIBMUTT multiple */
+#ifdef LIBMUTT /* multiple */
+      /* prune current folder from output if it's a folder, not a
+       * mailbox */
+      if (mutt_strncmp (name, mx.mbox, strlen (name)) || !noselect)
+        imap_add_folder (idata->delim, name, noselect, noinferiors, state,
+          0, 0, option(OPTIMAPLSUB)
+          && !ascii_strncasecmp(imap_next_word(idata->cmd.buf), "LIST", 4));
+
+      if (!option(OPTIMAPLSUB))
+      {
+          /* we're descending the tree one level at a time, so append
+           * `%' and ask for some more responses */
+        if (!noinferiors)
+        {
+          int depth = 0;
+          char *p = name;
+  
+          while ((p = strchr(p, idata->delim)))
+          {
+            ++p;
+            ++depth;
+          }
+          if (depth < 20)
+          {
+            char buf[LONG_STRING];
+  
+            snprintf(buf, sizeof(buf), "LIST \"\" \"%s%c%%\"",
+                     name, idata->delim);
+            browse_add_list_result(idata, buf, state, 0);
+          }
+        }
+      }
+      else
+      {
+        /* we already asked for the whole tree with LSUB, now we must
+         * back up and use LIST to get the flags (uw-imap doesn't set
+         * them reliably on LSUB responses) */
+        char *p;
+        int first = 1;
+
+        while ((p = strrchr(name, idata->delim))) 
+        {
+          char buf[LONG_STRING];
+
+          *p = '\0';
+          /* add a synthetic node, if needed */
+          imap_add_folder(idata->delim, name, 1, 0, state, 0, 1, 0);
+          if (first)
+          {
+            snprintf(buf, sizeof(buf), "LIST \"\" \"%s%c%%\"",
+                     name, idata->delim);
+            browse_add_list_result(idata, buf, state, 0);
+            first = 0;
+          }
+        }
+      }
+#endif /* LIBMUTT multiple */
     }
   }
+#ifdef LIBMUTT /* multiple */
+  while (*idata->cmd.buf == '*'
+         || !is_in_list(idata->cmd.buf, state->seq_list, 0, SEQLEN));
+
+  --state->pending;
+#else  /* LIBMUTT multiple */
   while ((mutt_strncmp (idata->cmd.buf, idata->cmd.seq, SEQLEN) != 0));
+#endif /* LIBMUTT multiple */
 
   FREE (&mx.mbox);
   return 0;
@@ -467,7 +699,11 @@
   int nsbused = 0;
   int rc;
 
+#ifdef LIBMUTT /* multiple */
   *nns = 0;
+#else
+  *nns;
+#endif
   nsbuf[nsblen-1] = '\0';
 
   imap_cmd_start (idata, "NAMESPACE");
diff -Nur --exclude=CVS --exclude=gtkhtml balsa-cvs/src/mailbox-node.c balsa-imap-multiple4/src/mailbox-node.c
--- balsa-cvs/src/mailbox-node.c	Sat Oct 13 16:24:17 2001
+++ balsa-imap-multiple4/src/mailbox-node.c	Mon Oct 15 20:01:15 2001
@@ -824,7 +824,7 @@
 
     d[0] = (gchar*) path;
     d[1] = NULL;
-    g_node_traverse(root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1,
+    g_node_traverse(root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
 		    (GNodeTraverseFunc) traverse_find_dir, d);
 
     return d[1] ? d[1] : root;
@@ -844,6 +844,8 @@
     const gchar *basename;
     gchar* url;
 
+    while (root->parent && BALSA_MAILBOX_NODE(root->parent->data)->dir)
+        root = root->parent;
     node = find_by_dir(root, fn);
     if (node != root)
 	return node;
