Index: camel/camel-store.h
===================================================================
--- camel/camel-store.h	(revision 10049)
+++ camel/camel-store.h	(working copy)
@@ -148,6 +148,7 @@ struct _CamelStore {
 #define CAMEL_STORE_FOLDER_INFO_RECURSIVE  (1 << 1)
 #define CAMEL_STORE_FOLDER_INFO_SUBSCRIBED (1 << 2)
 #define CAMEL_STORE_FOLDER_INFO_NO_VIRTUAL (1 << 3)  /* don't include vTrash/vJunk folders */
+#define CAMEL_STORE_FOLDER_INFO_SUBSCRIBEABLE (1 << 4)  /* only looking for subscriptions */
 
 typedef struct {
 	CamelServiceClass parent_class;
Index: camel/providers/imap/camel-imap-store-summary.h
===================================================================
--- camel/providers/imap/camel-imap-store-summary.h	(revision 10049)
+++ camel/providers/imap/camel-imap-store-summary.h	(working copy)
@@ -53,6 +53,8 @@ struct _CamelImapStoreNamespace {
 	char *path;		/* display path */
 	char *full_name;	/* real name */
 	char sep;		/* directory separator */
+
+	struct _CamelImapStoreNamespace *next;
 };
 
 struct _CamelImapStoreSummary {
@@ -63,7 +65,7 @@ struct _CamelImapStoreSummary {
 	/* header info */
 	guint32 version;	/* version of base part of file */
 	guint32 capabilities;
-	CamelImapStoreNamespace *namespace; /* eventually to be a list */
+	CamelImapStoreNamespace *namespace; /* list of namespaces, the first is always main namespace */
 };
 
 struct _CamelImapStoreSummaryClass {
@@ -73,9 +75,9 @@ struct _CamelImapStoreSummaryClass {
 CamelType			 camel_imap_store_summary_get_type	(void);
 CamelImapStoreSummary      *camel_imap_store_summary_new	(void);
 
-/* TODO: this api needs some more work, needs to support lists */
-CamelImapStoreNamespace *camel_imap_store_summary_namespace_new(CamelImapStoreSummary *s, const char *full_name, char dir_sep);
-void camel_imap_store_summary_namespace_set(CamelImapStoreSummary *s, CamelImapStoreNamespace *ns);
+void camel_imap_store_summary_namespace_set_main (CamelImapStoreSummary *s, const char *full_name, char dir_sep);
+void camel_imap_store_summary_namespace_add_secondary (CamelImapStoreSummary *s, const char *full_name, char dir_sep);
+CamelImapStoreNamespace *camel_imap_store_summary_get_main_namespace (CamelImapStoreSummary *s);
 CamelImapStoreNamespace *camel_imap_store_summary_namespace_find_path(CamelImapStoreSummary *s, const char *path);
 CamelImapStoreNamespace *camel_imap_store_summary_namespace_find_full(CamelImapStoreSummary *s, const char *full_name);
 
Index: camel/providers/imap/camel-imap-store.c
===================================================================
--- camel/providers/imap/camel-imap-store.c	(revision 10049)
+++ camel/providers/imap/camel-imap-store.c	(working copy)
@@ -185,8 +185,8 @@ camel_imap_store_finalize (CamelObject *
 	if (imap_store->storage_path)
 		g_free (imap_store->storage_path);
 
-	g_free (imap_store->namespace);
-	imap_store->namespace = NULL;
+	g_free (imap_store->users_namespace);
+	imap_store->users_namespace = NULL;
 
 	g_free (imap_store->custom_headers);
 }
@@ -198,7 +198,8 @@ camel_imap_store_init (gpointer object, 
 	
 	imap_store->istream = NULL;
 	imap_store->ostream = NULL;
-	
+
+	/* TODO: support dir_sep per namespace */
 	imap_store->dir_sep = '\0';
 	imap_store->current_folder = NULL;
 	imap_store->connected = FALSE;
@@ -258,8 +259,8 @@ construct (CamelService *service, CamelS
 		imap_store->parameters |= IMAP_PARAM_SUBSCRIPTIONS;
 	if (camel_url_get_param (url, "override_namespace") && camel_url_get_param (url, "namespace")) {
 		imap_store->parameters |= IMAP_PARAM_OVERRIDE_NAMESPACE;
-		g_free(imap_store->namespace);
-		imap_store->namespace = g_strdup (camel_url_get_param (url, "namespace"));
+		g_free(imap_store->users_namespace);
+		imap_store->users_namespace = g_strdup (camel_url_get_param (url, "namespace"));
 	}
 	if (camel_url_get_param (url, "check_all"))
 		imap_store->parameters |= IMAP_PARAM_CHECK_ALL;
@@ -297,11 +298,8 @@ construct (CamelService *service, CamelS
 
 		if (is->namespace) {
 			/* if namespace has changed, clear folder list */
-			if (imap_store->namespace && strcmp(imap_store->namespace, is->namespace->full_name) != 0) {
+			if (imap_store->users_namespace && strcmp(imap_store->users_namespace, is->namespace->full_name) != 0) {
 				camel_store_summary_clear((CamelStoreSummary *)is);
-			} else {
-				imap_store->namespace = g_strdup(is->namespace->full_name);
-				imap_store->dir_sep = is->namespace->sep;
 			}
 		}
  
@@ -327,9 +325,9 @@ imap_setv (CamelObject *object, CamelExc
 
 		switch (tag) {
 		case CAMEL_IMAP_STORE_NAMESPACE:
-			if (strcmp (store->namespace, args->argv[i].ca_str) != 0) {
-				g_free (store->namespace);
-				store->namespace = g_strdup (args->argv[i].ca_str);
+			if (strcmp (store->users_namespace, args->argv[i].ca_str) != 0) {
+				g_free (store->users_namespace);
+				store->users_namespace = g_strdup (args->argv[i].ca_str);
 				/* the current imap code will need to do a reconnect for this to take effect */
 				/*reconnect = TRUE;*/
 			}
@@ -401,7 +399,7 @@ imap_getv (CamelObject *object, CamelExc
 		
 		switch (tag) {
 		case CAMEL_IMAP_STORE_NAMESPACE:
-			*args->argv[i].ca_str = store->namespace;
+			*args->argv[i].ca_str = store->users_namespace;
 			break;
 		case CAMEL_IMAP_STORE_OVERRIDE_NAMESPACE:
 			*args->argv[i].ca_int = store->parameters & IMAP_PARAM_OVERRIDE_NAMESPACE ? TRUE : FALSE;
@@ -1399,10 +1397,8 @@ imap_connect (CamelService *service, Cam
 {
 	CamelImapStore *store = CAMEL_IMAP_STORE (service);
 	CamelImapResponse *response;
-	/*struct _namespaces *namespaces;*/
 	char *result, *name;
 	size_t len;
-	CamelImapStoreNamespace *ns;
 
 	if (((CamelOfflineStore *) store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
 		return TRUE;
@@ -1416,8 +1412,9 @@ imap_connect (CamelService *service, Cam
 	}
 	
 	/* Get namespace and hierarchy separator */
-	if ((store->capabilities & IMAP_CAPABILITY_NAMESPACE) &&
-	    !(store->parameters & IMAP_PARAM_OVERRIDE_NAMESPACE)) {
+	if (store->capabilities & IMAP_CAPABILITY_NAMESPACE) {
+		struct _namespaces *namespaces;
+
 		response = camel_imap_command (store, NULL, ex, "NAMESPACE");
 		if (!response)
 			goto done;
@@ -1426,41 +1423,85 @@ imap_connect (CamelService *service, Cam
 		if (!result)
 			goto done;
 		
-#if 0
-		/* new code... */
 		namespaces = imap_parse_namespace_response (result);
+
+		if (!(store->parameters & IMAP_PARAM_OVERRIDE_NAMESPACE)) {
+			g_free (store->users_namespace);
+			store->users_namespace = NULL;
+		}
+
+		if (namespaces && !store->users_namespace) {
+			struct _namespace *np = NULL;
+
+			if (namespaces->personal)
+				np = namespaces->personal;
+			else if (namespaces->other)
+				np = namespaces->other;
+			else if (namespaces->shared)
+				np = namespaces->shared;
+
+			if (np) {
+				store->users_namespace = g_strdup (np->prefix);
+			}
+		}
+
+		if (namespaces) {
+			#define add_all(_ns) 									\
+				if (_ns) {									\
+					struct _namespace *ns;							\
+														\
+					for (ns = _ns; ns; ns = ns->next) {					\
+						if (ns->prefix)							\
+							camel_imap_store_summary_namespace_add_secondary	\
+								(store->summary, ns->prefix, ns->delim);	\
+					}									\
+				}
+
+			add_all (namespaces->personal);
+			add_all (namespaces->other);
+			add_all (namespaces->shared);
+
+			#undef add_all
+		}
+
 		imap_namespaces_destroy (namespaces);
-		/* end new code */
-#endif
-		
-		name = camel_strstrcase (result, "NAMESPACE ((");
-		if (name) {
-			char *sep;
-			
-			name += 12;
-			store->namespace = imap_parse_string ((const char **) &name, &len);
-			if (name && *name++ == ' ') {
-				sep = imap_parse_string ((const char **) &name, &len);
-				if (sep) {
-					store->dir_sep = *sep;
-					g_free (sep);
+
+		if (!store->users_namespace) {
+			/* fallback for a broken result */
+			name = camel_strstrcase (result, "NAMESPACE ((");
+			if (name) {
+				char *sep;
+
+				name += 12;
+				store->users_namespace = imap_parse_string ((const char **) &name, &len);
+				if (name && *name++ == ' ') {
+					sep = imap_parse_string ((const char **) &name, &len);
+					if (sep) {
+						store->dir_sep = *sep;
+						g_free (sep);
+					}
 				}
 			}
 		}
 		g_free (result);
 	}
 	
-	if (!store->namespace)
-		store->namespace = g_strdup ("");
+	if (!store->users_namespace)
+		store->users_namespace = g_strdup ("");
 	
 	if (!store->dir_sep) {
+		const char *use_namespace = store->summary->namespace ? store->summary->namespace->full_name : NULL;
+
+		if (!use_namespace)
+			use_namespace = store->users_namespace;
+
 		if (store->server_level >= IMAP_LEVEL_IMAP4REV1) {
 			/* This idiom means "tell me the hierarchy separator
 			 * for the given path, even if that path doesn't exist.
 			 */
 			response = camel_imap_command (store, NULL, ex,
 						       "LIST %G \"\"",
-						       store->namespace);
+						       use_namespace);
 		} else {
 			/* Plain IMAP4 doesn't have that idiom, so we fall back
 			 * to "tell me about this folder", which will fail if
@@ -1468,7 +1509,7 @@ imap_connect (CamelService *service, Cam
 			 */
 			response = camel_imap_command (store, NULL, ex,
 						       "LIST \"\" %G",
-						       store->namespace);
+						       use_namespace);
 		}
 		if (!response)
 			goto done;
@@ -1484,30 +1525,19 @@ imap_connect (CamelService *service, Cam
 
 	}
 	
-	/* canonicalize the namespace to end with dir_sep */
-	len = strlen (store->namespace);
-	if (len && store->namespace[len - 1] != store->dir_sep) {
-		gchar *tmp;
-		
-		tmp = g_strdup_printf ("%s%c", store->namespace, store->dir_sep);
-		g_free (store->namespace);
-		store->namespace = tmp;
-	}
+	/* canonicalize the namespace to not end with dir_sep */
+	len = strlen (store->users_namespace);
+	if (len && store->users_namespace[len - 1] == store->dir_sep)
+		store->users_namespace[len - 1] = 0;
 	
-	ns = camel_imap_store_summary_namespace_new(store->summary, store->namespace, store->dir_sep);
-	camel_imap_store_summary_namespace_set(store->summary, ns);
+	camel_imap_store_summary_namespace_set_main (store->summary, store->users_namespace, store->dir_sep);
 	
 	if ((store->parameters & IMAP_PARAM_SUBSCRIPTIONS)
 	    && camel_store_summary_count((CamelStoreSummary *)store->summary) == 0) {
 		CamelStoreInfo *si;
-		char *pattern;
-		
-		get_folders_sync(store, store->namespace, ex);
-		if (camel_exception_is_set(ex))
-			goto done;
-		pattern = imap_concat(store, store->namespace, "*");
-		get_folders_sync(store, pattern, ex);
-		g_free (pattern);
+
+		/* look in all namespaces */
+		get_folders_sync (store, NULL, ex);
 		if (camel_exception_is_set(ex))
 			goto done;
 
@@ -1578,11 +1608,11 @@ imap_disconnect (CamelService *service, 
 		store->authtypes = NULL;
 	}
 	
-	if (store->namespace && !(store->parameters & IMAP_PARAM_OVERRIDE_NAMESPACE)) {
-		g_free (store->namespace);
-		store->namespace = NULL;
+	if (store->users_namespace && !(store->parameters & IMAP_PARAM_OVERRIDE_NAMESPACE)) {
+		g_free (store->users_namespace);
+		store->users_namespace = NULL;
 	}
-		
+
 	return TRUE;
 }
 
@@ -2424,9 +2454,14 @@ parse_list_response_as_folder_info (Came
 	return fi;
 }
 
-static int imap_match_pattern(char dir_sep, const char *pattern, const char *name)
+static int imap_match_pattern (CamelImapStoreNamespace *ns, const char *pattern, const char *name)
 {
-	char p, n;
+	char p, n, dir_sep;
+
+	if (!ns)
+		return TRUE;
+
+	dir_sep = ns->sep;
 
 	p = *pattern++;
 	n = *name++;
@@ -2481,7 +2516,7 @@ get_folders_free(void *k, void *v, void 
 }
 
 static void
-get_folders_sync(CamelImapStore *imap_store, const char *pattern, CamelException *ex)
+get_folders_sync(CamelImapStore *imap_store, const char *ppattern, CamelException *ex)
 {
 	CamelImapResponse *response;
 	CamelFolderInfo *fi, *hfi;
@@ -2489,51 +2524,81 @@ get_folders_sync(CamelImapStore *imap_st
 	int i, count, j;
 	GHashTable *present;
 	CamelStoreInfo *si;
+	const char *pattern = ppattern;
+	CamelImapStoreNamespace *ns;
 
 	/* We do a LIST followed by LSUB, and merge the results.  LSUB may not be a strict
 	   subset of LIST for some servers, so we can't use either or separately */
 	present = g_hash_table_new(folder_hash, folder_eq);
 
-	for (j=0;j<2;j++) {
-		response = camel_imap_command (imap_store, NULL, ex,
-					       "%s \"\" %G", j==1 ? "LSUB" : "LIST",
-					       pattern);
-		if (!response)
-			goto fail;
+	if (!pattern)
+		pattern = "";
+
+	for (ns = imap_store->summary->namespace; ns; ns = ns->next) {
+		char *tmp = NULL;
+
+		if (!ppattern) {
+			if (!ns->full_name || !*ns->full_name)
+				tmp = g_strdup ("*");
+			else
+				tmp = g_strdup_printf ("%s%c*", ns->full_name, ns->sep);
+			pattern = tmp;
+		}
 
-		for (i = 0; i < response->untagged->len; i++) {
-			list = response->untagged->pdata[i];
-			fi = parse_list_response_as_folder_info (imap_store, list);
-			if (fi) {
-				hfi = g_hash_table_lookup(present, fi->full_name);
-				if (hfi == NULL) {
-					if (j == 1) {
-						fi->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
-						if ((fi->flags & (CAMEL_IMAP_FOLDER_MARKED | CAMEL_IMAP_FOLDER_UNMARKED)))
-							imap_store->capabilities |= IMAP_CAPABILITY_useful_lsub;
+		for (j=0;j<2;j++) {
+			response = camel_imap_command (imap_store, NULL, ex,
+							"%s \"\" %G", j==1 ? "LSUB" : "LIST",
+							pattern);
+			if (!response)
+				goto fail;
+
+			for (i = 0; i < response->untagged->len; i++) {
+				list = response->untagged->pdata[i];
+				fi = parse_list_response_as_folder_info (imap_store, list);
+				if (fi && *fi->full_name) {
+					hfi = g_hash_table_lookup(present, fi->full_name);
+					if (hfi == NULL) {
+						if (j == 1) {
+							fi->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
+							if ((fi->flags & (CAMEL_IMAP_FOLDER_MARKED | CAMEL_IMAP_FOLDER_UNMARKED)))
+								imap_store->capabilities |= IMAP_CAPABILITY_useful_lsub;
+						}
+						g_hash_table_insert(present, fi->full_name, fi);
+					} else {
+						if (j == 1)
+							hfi->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
+						camel_folder_info_free(fi);
 					}
-					g_hash_table_insert(present, fi->full_name, fi);
-				} else {
-					if (j == 1)
-						hfi->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
-					camel_folder_info_free(fi);
+				} else if (fi) {
+					camel_folder_info_free (fi);
 				}
 			}
+			camel_imap_response_free (imap_store, response);
 		}
-		camel_imap_response_free (imap_store, response);
+
+		g_free (tmp);
+
+		/* look for matching only, if ppattern was non-NULL */
+		if (ppattern)
+			break;
 	}
 
 	/* Sync summary to match */
 
 	/* FIXME: we need to emit folder_create/subscribed/etc events for any new folders */
 	count = camel_store_summary_count((CamelStoreSummary *)imap_store->summary);
-
 	for (i=0;i<count;i++) {
+		const char *full_name;
+
 		si = camel_store_summary_index((CamelStoreSummary *)imap_store->summary, i);
 		if (si == NULL)
 			continue;
 
-		if (imap_match_pattern(imap_store->dir_sep, pattern, camel_imap_store_info_full_name(imap_store->summary, si))) {
+		full_name = camel_imap_store_info_full_name (imap_store->summary, si);
+		if (!full_name)
+			continue;
+
+		if (!ppattern || imap_match_pattern (camel_imap_store_summary_namespace_find_full (imap_store->summary, full_name), pattern, full_name)) {
 			if ((fi = g_hash_table_lookup(present, camel_store_info_path(imap_store->summary, si))) != NULL) {
 				if (((fi->flags ^ si->flags) & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED)) {
 					si->flags = (si->flags & ~CAMEL_FOLDER_SUBSCRIBED) | (fi->flags & CAMEL_FOLDER_SUBSCRIBED);
@@ -2554,8 +2619,9 @@ get_folders_sync(CamelImapStore *imap_st
 
 					g_free (dup_folder_name);
 					camel_exception_clear (&eex);
-				} else
+				} else {
 					camel_store_summary_remove ((CamelStoreSummary *)imap_store->summary, si);
+				}
 
 				count--;
 				i--;
@@ -2585,10 +2651,10 @@ dumpfi(CamelFolderInfo *fi)
 	}
 
 	while (fi) {
-		printf("%-40s %-30s %*s\n", fi->path, fi->full_name, depth*2+strlen(fi->url), fi->url);
+		printf("%-25s %-25s %*s\n", fi->name, fi->full_name, (int)(depth*2+strlen(fi->uri)), fi->uri);
 		if (fi->child)
 			dumpfi(fi->child);
-		fi = fi->sibling;
+		fi = fi->next;
 	}
 }
 #endif
@@ -2627,28 +2693,14 @@ static void
 refresh_refresh(CamelSession *session, CamelSessionThreadMsg *msg)
 {
 	struct _refresh_msg *m = (struct _refresh_msg *)msg;
-	CamelImapStore *store = (CamelImapStore *)m->store;
 
 	CAMEL_SERVICE_REC_LOCK(m->store, connect_lock);
 
 	if (!camel_imap_store_connected((CamelImapStore *)m->store, &m->ex))
 		goto done;
 
-	if (store->namespace && store->namespace[0]) {
-		char *pattern;
-		
-		get_folders_sync(store, "INBOX", &m->ex);
-		if (camel_exception_is_set(&m->ex))
-			goto done;
-		get_folders_sync(store, store->namespace, &m->ex);
-		if (camel_exception_is_set(&m->ex))
-			goto done;
-		pattern = imap_concat(store, store->namespace, "*");
-		get_folders_sync(store, pattern, &m->ex);
-		g_free(pattern);
-	} else {
-		get_folders_sync((CamelImapStore *)m->store, "*", &m->ex);
-	}
+	/* look in all namespaces */
+	get_folders_sync((CamelImapStore *)m->store, NULL, &m->ex);
 	camel_store_summary_save((CamelStoreSummary *)((CamelImapStore *)m->store)->summary);
 done:
 	CAMEL_SERVICE_REC_UNLOCK(m->store, connect_lock);
@@ -2715,6 +2767,7 @@ get_folder_info (CamelStore *store, cons
 	} else {
 		char *pattern;
 		int i;
+		CamelImapStoreNamespace *ns;
 
 		CAMEL_SERVICE_REC_LOCK(store, connect_lock);
 
@@ -2722,23 +2775,10 @@ get_folder_info (CamelStore *store, cons
 			goto fail;
 
 		if (top[0] == 0) {
-			if (imap_store->namespace && imap_store->namespace[0]) {
-				get_folders_sync(imap_store, "INBOX", ex);
-				if (camel_exception_is_set(ex))
-					goto fail;
-				
-				i = strlen(imap_store->namespace)-1;
-				pattern = g_alloca(i+5);
-				strcpy(pattern, imap_store->namespace);
-				while (i>0 && pattern[i] == imap_store->dir_sep)
-					pattern[i--] = 0;
-				i++;
-			} else {
-				pattern = g_alloca(2);
-				pattern[0] = '*';
-				pattern[1] = 0;
-				i=0;
-			}
+			pattern = g_alloca(2);
+			pattern[0] = '*';
+			pattern[1] = 0;
+			i=0;
 		} else {
 			char *name;
 			
@@ -2752,11 +2792,12 @@ get_folder_info (CamelStore *store, cons
 			g_free(name);
 		}
 
+		ns = camel_imap_store_summary_get_main_namespace (imap_store->summary);
 		get_folders_sync(imap_store, pattern, ex);
 		if (camel_exception_is_set(ex))
 			goto fail;
-		if (pattern[0] != '*' && imap_store->dir_sep) {
-			pattern[i] = imap_store->dir_sep;
+		if (pattern[0] != '*' && ns) {
+			pattern[i] = ns->sep;
 			pattern[i+1] = (flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE)?'*':'%';
 			pattern[i+2] = 0;
 			get_folders_sync(imap_store, pattern, ex);
@@ -2783,6 +2824,7 @@ get_folder_info_offline (CamelStore *sto
 	GPtrArray *folders;
 	char *pattern, *name;
 	int i;
+	CamelImapStoreNamespace *main_ns, *ns;
 
 	if (camel_debug("imap:folder_info"))
 		printf("get folder info offline\n");
@@ -2798,17 +2840,14 @@ get_folder_info_offline (CamelStore *sto
 
 	/* get starting point */
 	if (top[0] == 0) {
-		if (imap_store->namespace && imap_store->namespace[0]) {
-			name = g_strdup(imap_store->summary->namespace->full_name);
-			top = imap_store->summary->namespace->path;
-		} else
-			name = g_strdup("");
+		name = g_strdup("");
 	} else {
 		name = camel_imap_store_summary_full_from_path(imap_store->summary, top);
 		if (name == NULL)
 			name = camel_imap_store_summary_path_to_full(imap_store->summary, top, imap_store->dir_sep);
 	}
 
+	main_ns = camel_imap_store_summary_get_main_namespace (imap_store->summary);
 	pattern = imap_concat(imap_store, name, "*");
 
 	/* folder_info_build will insert parent nodes as necessary and mark
@@ -2818,16 +2857,25 @@ get_folder_info_offline (CamelStore *sto
 
 	for (i=0;i<camel_store_summary_count((CamelStoreSummary *)imap_store->summary);i++) {
 		CamelStoreInfo *si = camel_store_summary_index((CamelStoreSummary *)imap_store->summary, i);
+		const char *full_name;
 
 		if (si == NULL)
 			continue;
-		
-		if ((!strcmp(name, camel_imap_store_info_full_name(imap_store->summary, si))
-		     || imap_match_pattern(imap_store->dir_sep, pattern, camel_imap_store_info_full_name(imap_store->summary, si))
-		     || (include_inbox && !g_ascii_strcasecmp (camel_imap_store_info_full_name(imap_store->summary, si), "INBOX")))
-		    && ((imap_store->parameters & IMAP_PARAM_SUBSCRIPTIONS) == 0
-			|| (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED) == 0
-			|| (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED))) {
+
+		full_name = camel_imap_store_info_full_name (imap_store->summary, si);
+		if (!full_name || !*full_name)
+			continue;
+
+		ns = camel_imap_store_summary_namespace_find_full (imap_store->summary, full_name);
+
+		if ((g_str_equal (name, full_name)
+		     || imap_match_pattern (ns, pattern, full_name)
+		     || (include_inbox && !g_ascii_strcasecmp (full_name, "INBOX")))
+		    && ((ns == main_ns && 
+			((imap_store->parameters & IMAP_PARAM_SUBSCRIPTIONS) == 0
+			   || (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED) == 0))
+			|| (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED)
+			|| (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBEABLE) != 0)) {
 
 			fi = imap_build_folder_info(imap_store, camel_store_info_path((CamelStoreSummary *)imap_store->summary, si));
 			fi->unread = si->unread;
Index: camel/providers/imap/camel-imap-utils.c
===================================================================
--- camel/providers/imap/camel-imap-utils.c	(revision 10049)
+++ camel/providers/imap/camel-imap-utils.c	(working copy)
@@ -43,6 +43,7 @@
 
 #include "camel-imap-store.h"
 #include "camel-imap-summary.h"
+#include "camel-imap-store-summary.h"
 #include "camel-imap-utils.h"
 
 #define d(x)
@@ -1354,12 +1355,13 @@ char *
 imap_concat (CamelImapStore *imap_store, const char *prefix, const char *suffix)
 {
 	size_t len;
+	CamelImapStoreNamespace *ns = camel_imap_store_summary_get_main_namespace (imap_store->summary);
 	
 	len = strlen (prefix);
-	if (len == 0 || prefix[len - 1] == imap_store->dir_sep)
+	if (len == 0 || !ns || prefix[len - 1] == ns->sep)
 		return g_strdup_printf ("%s%s", prefix, suffix);
 	else
-		return g_strdup_printf ("%s%c%s", prefix, imap_store->dir_sep, suffix);
+		return g_strdup_printf ("%s%c%s", prefix, ns->sep, suffix);
 }
 
 char *
Index: camel/providers/imap/camel-imap-store.h
===================================================================
--- camel/providers/imap/camel-imap-store.h	(revision 10049)
+++ camel/providers/imap/camel-imap-store.h	(working copy)
@@ -139,8 +139,7 @@ struct _CamelImapStore {
 	/* Information about the server */
 	CamelImapServerLevel server_level;
 	guint32 capabilities, parameters;
-	/* NB: namespace should be handled by summary->namespace */
-	char *namespace, dir_sep, *base_url, *storage_path;
+	char *users_namespace, dir_sep, *base_url, *storage_path;
 	GHashTable *authtypes;
 	
 	time_t refresh_stamp;
Index: camel/providers/imap/ChangeLog
===================================================================
--- camel/providers/imap/ChangeLog	(revision 10050)
+++ camel/providers/imap/ChangeLog	(working copy)
@@ -1,3 +1,27 @@
+2009-02-12  Milan Crha  <mcrha@redhat.com>
+
+	** Fix for bug #413422
+
+	* camel-imap-store-summary.h: (struct _CamelImapStoreNamespace),
+	(camel_imap_store_summary_namespace_set_main),
+	(camel_imap_store_summary_namespace_add_secondary),
+	(camel_imap_store_summary_get_main_namespace):
+	* camel-imap-store-summary.c: (namespace_new), (namespace_find),
+	(camel_imap_store_summary_namespace_set_main),
+	(camel_imap_store_summary_namespace_add_secondary),
+	(camel_imap_store_summary_get_main_namespace),
+	(camel_imap_store_summary_namespace_find_path),
+	(camel_imap_store_summary_namespace_find_full), (namespace_free),
+	(namespace_clear), (namespaces_load), (namespaces_save),
+	(summary_header_load), (summary_header_save):
+	* camel-imap-store.h: (struct _CamelImapStore):
+	* camel-imap-store.c: (construct), (imap_connect),
+	(imap_match_pattern), (get_folders_sync), (refresh_refresh),
+	(get_folder_info), (get_folder_info_offline):
+	* camel-imap-utils.c: (imap_concat):
+	* camel-imap-folder.c: (imap_get_quota_info):
+	Read namespaces correctly and support subscribing to shared folders.
+
 2009-02-12  Milan Crha  <mcrha@redhat.com>
 
 	** Fix for bug #534938
Index: camel/providers/imap/camel-imap-folder.c
===================================================================
--- camel/providers/imap/camel-imap-folder.c	(revision 10050)
+++ camel/providers/imap/camel-imap-folder.c	(working copy)
@@ -3964,7 +3964,9 @@ imap_get_quota_info (CamelFolder *folder
 		goto done;
 
 	if (imap_store->capabilities & IMAP_CAPABILITY_QUOTA) {
-		char *folder_name = camel_imap_store_summary_path_to_full (imap_store->summary, camel_folder_get_full_name (folder), imap_store->dir_sep);
+		const char *full_name = camel_folder_get_full_name (folder);
+		CamelImapStoreNamespace *ns = camel_imap_store_summary_namespace_find_full (imap_store->summary, full_name);
+		char *folder_name = camel_imap_store_summary_path_to_full (imap_store->summary, full_name, ns ? ns->sep : '/');
 
 		response = camel_imap_command (imap_store, NULL, NULL, "GETQUOTAROOT \"%s\"", folder_name);
 
Index: camel/providers/imap/camel-imap-store-summary.c
===================================================================
--- camel/providers/imap/camel-imap-store-summary.c	(revision 10049)
+++ camel/providers/imap/camel-imap-store-summary.c	(working copy)
@@ -45,8 +45,6 @@
 
 #define _PRIVATE(o) (((CamelImapStoreSummary *)(o))->priv)
 
-static void namespace_clear(CamelStoreSummary *s);
-
 static int summary_header_load(CamelStoreSummary *, FILE *);
 static int summary_header_save(CamelStoreSummary *, FILE *);
 
@@ -362,8 +360,8 @@ camel_imap_store_summary_full_from_path(
 	return name;
 }
 
-/* TODO: this api needs some more work */
-CamelImapStoreNamespace *camel_imap_store_summary_namespace_new(CamelImapStoreSummary *s, const char *full_name, char dir_sep)
+static CamelImapStoreNamespace *
+namespace_new (CamelImapStoreSummary *s, const char *full_name, char dir_sep)
 {
 	CamelImapStoreNamespace *ns;
 	char *p, *o, c;
@@ -389,12 +387,96 @@ CamelImapStoreNamespace *camel_imap_stor
 	return ns;
 }
 
-void camel_imap_store_summary_namespace_set(CamelImapStoreSummary *s, CamelImapStoreNamespace *ns)
+static CamelImapStoreNamespace *
+namespace_find (CamelImapStoreNamespace *ns, const char *full_name, char dir_sep)
 {
-	d(printf("Setting namesapce to '%s' '%c' -> '%s'\n", ns->full_name, ns->sep, ns->path));
-	namespace_clear((CamelStoreSummary *)s);
-	s->namespace = ns;
-	camel_store_summary_touch((CamelStoreSummary *)s);
+	if (!ns || !full_name)
+		return NULL;
+
+	while (ns) {
+		int len = strlen (ns->full_name);
+
+		if ((g_ascii_strcasecmp (ns->full_name, full_name) == 0 ||
+		    (g_ascii_strncasecmp (ns->full_name, full_name, len) == 0
+		    && len + 1 == strlen (full_name) && full_name [len] == ns->sep))&& (!dir_sep || ns->sep == dir_sep)) {
+			break;
+		}
+		ns = ns->next;
+	}
+
+	return ns;
+}
+
+void
+camel_imap_store_summary_namespace_set_main (CamelImapStoreSummary *s, const char *full_name, char dir_sep)
+{
+	CamelImapStoreNamespace *ns;
+
+	g_return_if_fail (s != NULL);
+	g_return_if_fail (full_name != NULL);
+
+	ns = namespace_find (s->namespace, full_name, dir_sep);
+
+	if (ns) {
+		/* is in the list of known namespaces already */
+		if (ns != s->namespace) {
+			CamelImapStoreNamespace *prev = s->namespace;
+
+			while (prev && prev->next != ns)
+				prev = prev->next;
+
+			g_return_if_fail (prev != NULL);
+
+			/* move it to the first */
+			prev->next = ns->next;
+			ns->next = s->namespace;
+			s->namespace = ns;
+
+			/* fix a dir separator, for the inherit/guess option */
+			if (dir_sep != 0)
+				s->namespace->sep = dir_sep;
+		} else
+			return;
+	} else {
+		if (!dir_sep && s->namespace)
+			dir_sep = s->namespace->sep; /* inherit */
+		else if (!dir_sep)
+			dir_sep = '/'; /* guess */
+
+		ns = namespace_new (s, full_name, dir_sep);
+		if (ns) {
+			ns->next = s->namespace;
+			s->namespace = ns;
+		}
+	}
+
+	camel_store_summary_touch ((CamelStoreSummary *)s);
+}
+
+void
+camel_imap_store_summary_namespace_add_secondary (CamelImapStoreSummary *s, const char *full_name, char dir_sep)
+{
+	CamelImapStoreNamespace **tail;
+
+	g_return_if_fail (s != NULL);
+	g_return_if_fail (full_name != NULL);
+
+	if (namespace_find (s->namespace, full_name, dir_sep))
+		return;
+
+	for (tail = &s->namespace; *tail; tail = &((*tail)->next)) {
+		/* do nothing, just keep moving to the last */
+	}
+
+	*tail = namespace_new (s, full_name, dir_sep);
+}
+
+CamelImapStoreNamespace *
+camel_imap_store_summary_get_main_namespace (CamelImapStoreSummary *s)
+{
+	g_return_val_if_fail (s != NULL, NULL);
+
+	return s->namespace;
 }
 
 CamelImapStoreNamespace *
@@ -403,7 +485,6 @@ camel_imap_store_summary_namespace_find_
 	int len;
 	CamelImapStoreNamespace *ns;
 
-	/* NB: this currently only compares against 1 namespace, in future compare against others */
 	ns = s->namespace;
 	while (ns) {
 		len = strlen(ns->path);
@@ -411,10 +492,10 @@ camel_imap_store_summary_namespace_find_
 		    || (strncmp(ns->path, path, len) == 0
 			&& (path[len] == '/' || path[len] == 0)))
 			break;
-		ns = NULL;
+		ns = ns->next;
 	}
 
-	/* have a default? */
+	/* NULL indicates not found */
 	return ns;
 }
 
@@ -424,7 +505,6 @@ camel_imap_store_summary_namespace_find_
 	int len;
 	CamelImapStoreNamespace *ns;
 
-	/* NB: this currently only compares against 1 namespace, in future compare against others */
 	ns = s->namespace;
 	while (ns) {
 		len = strlen(ns->full_name);
@@ -433,15 +513,15 @@ camel_imap_store_summary_namespace_find_
 		    || (strncmp(ns->full_name, full, len) == 0
 			&& (full[len] == ns->sep || full[len] == 0)))
 			break;
-		ns = NULL;
+		ns = ns->next;
 	}
 
-	/* have a default? */
+	/* NULL indicates not found */
 	return ns;
 }
 
 static void
-namespace_free(CamelStoreSummary *s, CamelImapStoreNamespace *ns)
+namespace_free (CamelImapStoreSummary *is, CamelImapStoreNamespace *ns)
 {
 	g_free(ns->path);
 	g_free(ns->full_name);
@@ -449,43 +529,59 @@ namespace_free(CamelStoreSummary *s, Cam
 }
 
 static void
-namespace_clear(CamelStoreSummary *s)
+namespace_clear (CamelImapStoreSummary *is)
 {
-	CamelImapStoreSummary *is = (CamelImapStoreSummary *)s;
+	while (is->namespace) {
+		CamelImapStoreNamespace *next = is->namespace->next;
 
-	if (is->namespace)
-		namespace_free(s, is->namespace);
-	is->namespace = NULL;
+		namespace_free (is, is->namespace);
+		is->namespace = next;
+	}
 }
 
-static CamelImapStoreNamespace *
-namespace_load(CamelStoreSummary *s, FILE *in)
+static gboolean
+namespaces_load (CamelImapStoreSummary *s, FILE *in, guint count)
 {
-	CamelImapStoreNamespace *ns;
+	CamelImapStoreNamespace *ns, **tail;
 	guint32 sep = '/';
 
-	ns = g_malloc0(sizeof(*ns));
-	if (camel_file_util_decode_string(in, &ns->path) == -1
-	    || camel_file_util_decode_string(in, &ns->full_name) == -1
-	    || camel_file_util_decode_uint32(in, &sep) == -1) {
-		namespace_free(s, ns);
-		ns = NULL;
-	} else {
-		ns->sep = sep;
+	namespace_clear (s);
+
+	tail = &s->namespace;
+
+	while (count > 0) {
+		ns = g_malloc0 (sizeof(*ns));
+		if (camel_file_util_decode_string (in, &ns->path) == -1
+		    || camel_file_util_decode_string (in, &ns->full_name) == -1
+		    || camel_file_util_decode_uint32 (in, &sep) == -1) {
+			namespace_free (s, ns);
+			return FALSE;
+		} else {
+			ns->sep = sep;
+
+			*tail = ns;
+			tail = &ns->next;
+		}
+
+		count --;
 	}
 
-	return ns;
+	return count == 0;
 }
 
-static int
-namespace_save(CamelStoreSummary *s, FILE *in, CamelImapStoreNamespace *ns)
+static gboolean
+namespaces_save (CamelImapStoreSummary *s, FILE *in, CamelImapStoreNamespace *ns)
 {
-	if (camel_file_util_encode_string(in, ns->path) == -1
-	    || camel_file_util_encode_string(in, ns->full_name) == -1
-	    || camel_file_util_encode_uint32(in, (guint32)ns->sep) == -1)
-		return -1;
+	while (ns) {
+		if (camel_file_util_encode_string(in, ns->path) == -1
+	    	    || camel_file_util_encode_string(in, ns->full_name) == -1
+		    || camel_file_util_encode_uint32(in, (guint32)ns->sep) == -1)
+			return FALSE;
 
-	return 0;
+		ns = ns->next;
+	}
+
+	return TRUE;
 }
 
 static int
@@ -494,7 +590,7 @@ summary_header_load(CamelStoreSummary *s
 	CamelImapStoreSummary *is = (CamelImapStoreSummary *)s;
 	gint32 version, capabilities, count;
 
-	namespace_clear(s);
+	namespace_clear (is);
 
 	if (camel_imap_store_summary_parent->summary_header_load((CamelStoreSummary *)s, in) == -1
 	    || camel_file_util_decode_fixed_int32(in, &version) == -1)
@@ -507,15 +603,13 @@ summary_header_load(CamelStoreSummary *s
 		return -1;
 	}
 
-	/* note file format can be expanded to contain more namespaces, but only 1 at the moment */
 	if (camel_file_util_decode_fixed_int32(in, &capabilities) == -1
-	    || camel_file_util_decode_fixed_int32(in, &count) == -1
-	    || count > 1)
+	    || camel_file_util_decode_fixed_int32(in, &count) == -1)
 		return -1;
 
 	is->capabilities = capabilities;
-	if (count == 1) {
-		if ((is->namespace = namespace_load(s, in)) == NULL)
+	if (count >= 1) {
+		if (!namespaces_load (is, in, count))
 			return -1;
 	}
 
@@ -526,9 +620,12 @@ static int
 summary_header_save(CamelStoreSummary *s, FILE *out)
 {
 	CamelImapStoreSummary *is = (CamelImapStoreSummary *)s;
-	guint32 count;
+	guint32 count = 0;
+	CamelImapStoreNamespace *ns;
 
-	count = is->namespace?1:0;
+	for (ns = is->namespace; ns; ns = ns->next) {
+		count++;
+	}
 
 	/* always write as latest version */
 	if (camel_imap_store_summary_parent->summary_header_save((CamelStoreSummary *)s, out) == -1
@@ -537,7 +634,7 @@ summary_header_save(CamelStoreSummary *s
 	    || camel_file_util_encode_fixed_int32(out, count) == -1)	    
 		return -1;
 
-	if (is->namespace && namespace_save(s, out, is->namespace) == -1)
+	if (!namespaces_save (is, out, is->namespace))
 		return -1;
 
 	return 0;
Index: camel/ChangeLog
===================================================================
--- camel/ChangeLog	(revision 10049)
+++ camel/ChangeLog	(working copy)
@@ -1,3 +1,9 @@
+2009-02-12  Milan Crha  <mcrha@redhat.com>
+
+	** Part of fix for bug #413422
+
+	* camel-store.h: New flag CAMEL_STORE_FOLDER_INFO_SUBSCRIBEABLE.
+
 2009-02-09  Milan Crha  <mcrha@redhat.com>
 
 	** Fix for bug #266147
