diff --git a/src/camel/ChangeLog b/src/camel/ChangeLog
index 18bf44d..2664419 100644
--- a/src/camel/ChangeLog
+++ b/src/camel/ChangeLog
@@ -1,3 +1,13 @@
+2009-05-19  Johnny Jacob  <jjohnny@novell.com>
+
+	* camel-mapi-store.c (mapi_folders_sync): Retrive public folders one level
+	at a time.
+
+2009-04-30  Johnny Jacob  <jjohnny@novell.com>
+
+	* camel-mapi-store.c (mapi_folders_sync): Do not download public folder
+	list by default.
+
 2009-04-24  Milan Crha  <mcrha@redhat.com>
 
 	** Part of fix for bug #563954
diff --git a/src/camel/camel-mapi-folder.c b/src/camel/camel-mapi-folder.c
index 47c0f58..02d5366 100644
--- a/src/camel/camel-mapi-folder.c
+++ b/src/camel/camel-mapi-folder.c
@@ -1648,7 +1648,7 @@ camel_mapi_folder_class_init (CamelMapiFolderClass *camel_mapi_folder_class)
 	camel_folder_class->get_message = mapi_folder_get_message;
  	camel_folder_class->rename = mapi_folder_rename;
 	camel_folder_class->search_by_expression = mapi_folder_search_by_expression;
-	camel_folder_class->cmp_uids = mapi_cmp_uids;
+	/* camel_folder_class->cmp_uids = mapi_cmp_uids; */
 /* 	camel_folder_class->get_message_info = mapi_get_message_info; */
 /* 	camel_folder_class->search_by_uids = mapi_folder_search_by_uids;  */
 	camel_folder_class->search_free = mapi_folder_search_free;
diff --git a/src/camel/camel-mapi-store.c b/src/camel/camel-mapi-store.c
index 62d00e7..678020b 100644
--- a/src/camel/camel-mapi-store.c
+++ b/src/camel/camel-mapi-store.c
@@ -109,7 +109,7 @@ static gboolean mapi_folder_subscribed (CamelStore *store, const char *folder_na
 static void		mapi_unsubscribe_folder(CamelStore *, const char *, CamelException *);
 static void		mapi_noop(CamelStore *, CamelException *);
 static CamelFolderInfo * mapi_build_folder_info(CamelMapiStore *mapi_store, const char *parent_name, const char *folder_name);
-static void mapi_folders_sync (CamelMapiStore *store, CamelException *ex);
+static void mapi_folders_sync (CamelMapiStore *store, char *top, guint32 flags, CamelException *ex);
 static gboolean mapi_fid_is_system_folder (CamelMapiStore *mapi_store, const char *fid);
 
 static guint
@@ -893,11 +893,12 @@ mapi_get_folder_info_offline (CamelStore *store, const char *top,
 	GPtrArray *folders;
 	char *path, *name;
 	int i;
-	gboolean recursive, subscribed, info_fast, favourites = false;
+	gboolean recursive, subscribed, info_fast, favourites , subscription_list = false;
 
 	recursive = (flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE);
 	subscribed = (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED);
 	info_fast = (flags & CAMEL_STORE_FOLDER_INFO_FAST);
+	subscription_list = (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST);
 
 	folders = g_ptr_array_new ();
 
@@ -923,7 +924,8 @@ mapi_get_folder_info_offline (CamelStore *store, const char *top,
 			continue;
 
 		/* Based on exchange connector. Allow only All Public Folders heirarchy */
-		if ((!subscribed) && info_fast) 
+		/* if ((!subscribed) && info_fast)  */
+		if (subscription_list)
 			if (!(si->flags & CAMEL_MAPI_FOLDER_PUBLIC)) continue;
 
 		/*Allow Mailbox and Favourites (Subscribed public folders)*/
@@ -966,7 +968,8 @@ mapi_get_folder_info_offline (CamelStore *store, const char *top,
 	}
 
 	/*FIXME*/
-	if (!((!subscribed) && info_fast) && top[0] == '\0') {
+	/* if (!((!subscribed) && info_fast) && top[0] == '\0') { */
+	if (!(subscription_list) && top[0] == '\0') {
 		fi = mapi_build_folder_info(mapi_store, NULL, DISPLAY_NAME_FAVOURITES);
 		fi->flags |= CAMEL_FOLDER_NOSELECT;
 		fi->flags |= CAMEL_FOLDER_SYSTEM;
@@ -1090,12 +1093,13 @@ camel_mapi_store_connected (CamelMapiStore *store, CamelException *ex)
 }
 
 static void
-mapi_folders_sync (CamelMapiStore *store, CamelException *ex)
+mapi_folders_sync (CamelMapiStore *store, char *top, guint32 flags, CamelException *ex)
 {
 	CamelMapiStorePrivate  *priv = store->priv;
 	gboolean status;
 	GSList *folder_list = NULL, *temp_list = NULL, *list = NULL;
 	char *url, *temp_url;
+	gboolean subscription_list = false;
 	CamelFolderInfo *info = NULL;
 	CamelMapiStoreInfo *mapi_si = NULL;
 
@@ -1112,16 +1116,30 @@ mapi_folders_sync (CamelMapiStore *store, CamelException *ex)
 		return;
 	}
 
-	status = exchange_mapi_get_folders_list (&folder_list);
-	if (!status) {
-		g_warning ("Could not get folder list..\n");
-		return;
-	}
+	subscription_list = (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST);
+
+	/* Based on exchange connector. Fetch the public folder tree*/
+	if (subscription_list) {
+		/*Consult the name <-> fid hash table for a FID.*/
+		gchar *parent_id = NULL;
+		mapi_id_t pid = 0;
+
+		parent_id = (top) ? g_strdup (camel_mapi_store_folder_id_lookup (store, top)) : NULL;
+		printf("%s(%d):%s:PARENT ID : %s \n", __FILE__, __LINE__, __PRETTY_FUNCTION__, parent_id);
+		exchange_mapi_util_mapi_id_from_string (parent_id, &pid);
+
+		status = exchange_mapi_get_pf_folders_list (&folder_list, pid, 1);
 
-	status = exchange_mapi_get_pf_folders_list (&folder_list);
-	if (!status) {
-		g_warning ("Could not get Public folder list..\n");
-//		return;
+		if (!status)
+			g_warning ("Could not get Public folder list..\n");
+
+		g_free (parent_id);
+	} else {
+		status = exchange_mapi_get_folders_list (&folder_list);
+		if (!status) {
+			g_warning ("Could not get folder list..\n");
+			return;
+		}
 	}
 
 	temp_list = folder_list;
@@ -1216,7 +1234,10 @@ mapi_get_folder_info(CamelStore *store, const char *top, guint32 flags, CamelExc
 	}
 
 	if (check_for_connection((CamelService *)store, ex)) {
-		mapi_folders_sync (mapi_store, ex);
+		/*TODO : Need to fetch folderid for subscriptions. */
+		/* mapi_folders_sync (mapi_store, flags, top, ex); */
+		mapi_folders_sync (mapi_store, top, flags, ex);
+
 		if (camel_exception_is_set (ex)) {
 			CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
 			return NULL;
diff --git a/src/libexchangemapi/ChangeLog b/src/libexchangemapi/ChangeLog
index 674843a..8062f84 100644
--- a/src/libexchangemapi/ChangeLog
+++ b/src/libexchangemapi/ChangeLog
@@ -1,3 +1,10 @@
+2009-05-19  Johnny Jacob  <jjohnny@novell.com>
+
+	* exchange-mapi-connection.c (get_child_folders): Added support
+	for depth.
+	(exchange_mapi_get_pf_folders_list): Added support for specifying a parent
+	folder for fetching public folder heirarchy and specify depth.
+
 2009-04-07  Milan Crha  <mcrha@redhat.com>
 
 	* exchange-mapi-connection.c: (mapi_profile_load):
diff --git a/src/libexchangemapi/exchange-mapi-connection.c b/src/libexchangemapi/exchange-mapi-connection.c
index f81add6..483c70c 100644
--- a/src/libexchangemapi/exchange-mapi-connection.c
+++ b/src/libexchangemapi/exchange-mapi-connection.c
@@ -2420,8 +2420,20 @@ cleanup:
 	return result;
 }
 
+/** 
+ * get_child_folders:
+ * @mem_ctx: 
+ * @folder_heir: Type of heirarchy
+ * @parent: Parent object to start a recursive traversal.
+ * @folder_id: Folder to open.
+ * @mapi_folders: List for collecting folder objects.
+ * @depth: Level in the folder tree where to stop traversal.
+ *
+ * Returns: TRUE if we encounter no errors.
+ **/
 static gboolean
-get_child_folders(TALLOC_CTX *mem_ctx, ExchangeMAPIFolderCategory folder_hier, mapi_object_t *parent, mapi_id_t folder_id, GSList **mapi_folders)
+get_child_folders(TALLOC_CTX *mem_ctx, ExchangeMAPIFolderCategory folder_hier, mapi_object_t *parent, 
+		  mapi_id_t folder_id, GSList **mapi_folders, gint32 depth)
 {
 	enum MAPISTATUS		retval;
 	mapi_object_t		obj_folder;
@@ -2435,6 +2447,9 @@ get_child_folders(TALLOC_CTX *mem_ctx, ExchangeMAPIFolderCategory folder_hier, m
 	g_return_val_if_fail (mem_ctx != NULL, FALSE);
 	g_return_val_if_fail (parent != NULL, FALSE);
 
+	/*We reached the depth we wanted.*/
+	if (!depth ) return true;
+
 	mapi_object_init(&obj_folder);
 	mapi_object_init(&obj_table);
 
@@ -2446,6 +2461,7 @@ get_child_folders(TALLOC_CTX *mem_ctx, ExchangeMAPIFolderCategory folder_hier, m
 	}
 
 	/* Get the hierarchy table */
+	/* TODO : Use flags for controlling fetch depth */
 	retval = GetHierarchyTable(&obj_folder, &obj_table, 0, &row_count);
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr("GetHierarchyTable", GetLastError());
@@ -2473,6 +2489,8 @@ get_child_folders(TALLOC_CTX *mem_ctx, ExchangeMAPIFolderCategory folder_hier, m
 		goto cleanup;
 	}
 
+	depth--;
+
 	for (i = 0; i < rowset.cRows; i++) {
 		ExchangeMAPIFolder *folder = NULL;
 		gchar *newname = NULL;
@@ -2488,13 +2506,17 @@ get_child_folders(TALLOC_CTX *mem_ctx, ExchangeMAPIFolderCategory folder_hier, m
 			class = IPF_NOTE;
 
 		newname = utf8tolinux (name);
-		g_print("\n|---+ %-15s : (Container class: %s %016" G_GINT64_MODIFIER "X) UnRead : %d Total : %d ", newname, class, *fid, unread ? *unread : 0, total ? *total : 0);
+		g_print("\n|---+ %-15s : (Container class: %s %016" G_GINT64_MODIFIER "X) UnRead : %d Total : %d ", 
+			newname, class, *fid, unread ? *unread : 0, total ? *total : 0);
+
+		folder = exchange_mapi_folder_new (newname, class, folder_hier, *fid, folder_id,
+						   child ? *child : 0, unread ? *unread : 0, total ? *total : 0);
 
-		folder = exchange_mapi_folder_new (newname, class, folder_hier, *fid, folder_id, child ? *child : 0, unread ? *unread : 0, total ? *total : 0);
 		*mapi_folders = g_slist_prepend (*mapi_folders, folder);
 
-		if (child && *child)
-			result = (result && get_child_folders(mem_ctx, folder_hier, &obj_folder, *fid, mapi_folders));
+		if (child && *child && (depth != 0))
+			result = (result && get_child_folders(mem_ctx, folder_hier, &obj_folder, *fid, 
+							      mapi_folders, depth));
 
 		g_free (newname);
 	}
@@ -2714,7 +2736,7 @@ exchange_mapi_get_folders_list (GSList **mapi_folders)
 	*mapi_folders = g_slist_prepend (*mapi_folders, folder);
 
 	/* FIXME: check status of get_child_folders */
-	get_child_folders (mem_ctx, MAPI_PERSONAL_FOLDER, &obj_store, mailbox_id, mapi_folders);
+	get_child_folders (mem_ctx, MAPI_PERSONAL_FOLDER, &obj_store, mailbox_id, mapi_folders, -1);
 
 	g_free(utf8_mailbox_name);
 
@@ -2738,7 +2760,7 @@ cleanup:
 }
 
 gboolean 
-exchange_mapi_get_pf_folders_list (GSList **mapi_folders)
+exchange_mapi_get_pf_folders_list (GSList **mapi_folders, mapi_id_t parent_fid, gint depth)
 {
 	enum MAPISTATUS 	retval;
 	TALLOC_CTX 		*mem_ctx;
@@ -2746,6 +2768,7 @@ exchange_mapi_get_pf_folders_list (GSList **mapi_folders)
 	gboolean 		result = FALSE;
 	mapi_id_t		mailbox_id;
 	ExchangeMAPIFolder 	*folder;
+	mapi_object_t obj_parent_folder;
 
 	d(g_print("\n%s: Entering %s ", G_STRLOC, G_STRFUNC));
 
@@ -2753,6 +2776,7 @@ exchange_mapi_get_pf_folders_list (GSList **mapi_folders)
 	LOGALL();
 	mem_ctx = talloc_init("ExchangeMAPI_PF_GetFoldersList");
 	mapi_object_init(&obj_store);
+	mapi_object_init(&obj_parent_folder);
 
 	/* Open the PF message store */
 	retval = OpenPublicFolder(global_mapi_session, &obj_store);
@@ -2761,11 +2785,19 @@ exchange_mapi_get_pf_folders_list (GSList **mapi_folders)
 		goto cleanup;
 	}
 
-	/* Prepare the directory listing */
-	retval = GetDefaultPublicFolder(&obj_store, &mailbox_id, olFolderPublicIPMSubtree);
-	if (retval != MAPI_E_SUCCESS) {
-		mapi_errstr("GetDefaultPublicFolder", GetLastError());
-		goto cleanup;
+	/*If we have parent_fid , then we need a handle on folder object for get_child_folders */
+	if (parent_fid) {
+		retval = OpenFolder(&obj_store, parent_fid, &obj_parent_folder);
+		if (retval != MAPI_E_SUCCESS) {
+			mapi_errstr("OpenFolder", GetLastError());
+			goto cleanup;
+		}
+	} else {
+		retval = GetDefaultPublicFolder(&obj_store, &mailbox_id, olFolderPublicIPMSubtree);
+		if (retval != MAPI_E_SUCCESS) {
+			mapi_errstr("GetDefaultPublicFolder", GetLastError());
+			goto cleanup;
+		}
 	}
 
 	/*  TODO : Localized string */
@@ -2777,12 +2809,14 @@ exchange_mapi_get_pf_folders_list (GSList **mapi_folders)
 	*mapi_folders = g_slist_prepend (*mapi_folders, folder);
 
 	/* FIXME: check status of get_child_folders */
-	get_child_folders (mem_ctx, MAPI_FAVOURITE_FOLDER, &obj_store, mailbox_id, mapi_folders);
+	get_child_folders (mem_ctx, MAPI_FAVOURITE_FOLDER, parent_fid ? &obj_parent_folder : &obj_store,
+			   parent_fid ? parent_fid : mailbox_id, mapi_folders, depth);
 
 	result = TRUE;
 
 cleanup:
 	mapi_object_release(&obj_store);
+	mapi_object_release(&obj_parent_folder);
 	talloc_free (mem_ctx);
 	LOGNONE();
 	UNLOCK();
diff --git a/src/libexchangemapi/exchange-mapi-connection.h b/src/libexchangemapi/exchange-mapi-connection.h
index 95b085d..7f0d641 100644
--- a/src/libexchangemapi/exchange-mapi-connection.h
+++ b/src/libexchangemapi/exchange-mapi-connection.h
@@ -175,7 +175,8 @@ exchange_mapi_move_items ( mapi_id_t src_fid, mapi_id_t dest_fid, GSList *mids);
 
 
 gboolean exchange_mapi_get_folders_list (GSList **mapi_folders); 
-gboolean exchange_mapi_get_pf_folders_list (GSList **mapi_folders); 
+gboolean exchange_mapi_get_pf_folders_list (GSList **mapi_folders, mapi_id_t parent_id,
+					    gint depth);
 
 struct SPropTagArray *
 exchange_mapi_util_resolve_named_props (uint32_t olFolder, mapi_id_t fid, 
