folder_info_from_store_summary (CamelEwsStore *store,
                                const gchar *top,
                                guint32 flags,
				GCancellable *cancellable,
                                GError **error)
{
	CamelEwsStoreSummary *ews_summary;
	GPtrArray *folder_infos = NULL;
	CamelFolderInfo *root_fi = NULL, *fi;

	/* search in public folders */
	if ((flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST) != 0) {
		GHashTable *folders_by_id;
		GSList *fiter;
		GList *esources = NULL;
		gchar *hosturl = NULL, *username = NULL;

		g_mutex_lock (&store->priv->get_finfo_lock);

		if (!store->priv->public_folders) {
			g_mutex_unlock (&store->priv->get_finfo_lock);
			return NULL;
		}

		folder_infos = g_ptr_array_new ();
		folders_by_id = g_hash_table_new (g_str_hash, g_str_equal);

		for (fiter = store->priv->public_folders; fiter != NULL; fiter = g_slist_next (fiter)) {
			EEwsFolder *folder = fiter->data;
			const EwsFolderId *fid;

			if (!folder)
				continue;

			fid = e_ews_folder_get_id (folder);
			if (!fid || !fid->id)
				continue;

			g_hash_table_insert (folders_by_id, fid->id, folder);
		}

		fi = camel_folder_info_new ();
		fi->full_name = g_strdup (EWS_PUBLIC_FOLDER_ROOT_DISPLAY_NAME);
		fi->display_name = g_strdup (fi->full_name);
		fi->flags = CAMEL_FOLDER_SYSTEM | CAMEL_FOLDER_NOSELECT;
		fi->unread = -1;
		fi->total = -1;

		g_ptr_array_add (folder_infos, fi);

		for (fiter = store->priv->public_folders; fiter != NULL; fiter = g_slist_next (fiter)) {
			EEwsFolder *folder = fiter->data;
			const EwsFolderId *fid;

			if (!folder)
				continue;

			fid = e_ews_folder_get_id (folder);
			if (!fid || !fid->id)
				continue;

			fi = camel_folder_info_new ();
			fi->full_name = get_public_folder_full_name (folder, folders_by_id);
			fi->display_name = g_strdup (e_ews_folder_get_name (folder));
			fi->flags = 0;
			fi->unread = e_ews_folder_get_unread_count (folder);
			fi->total = e_ews_folder_get_total_count (folder);

			switch (e_ews_folder_get_folder_type (folder)) {
			case E_EWS_FOLDER_TYPE_CALENDAR:
				fi->flags |= CAMEL_FOLDER_TYPE_EVENTS;
				break;
			case E_EWS_FOLDER_TYPE_CONTACTS:
				fi->flags |= CAMEL_FOLDER_TYPE_CONTACTS;
				break;
			case E_EWS_FOLDER_TYPE_TASKS:
				fi->flags |= CAMEL_FOLDER_TYPE_TASKS;
				break;
			case E_EWS_FOLDER_TYPE_MEMOS:
				fi->flags |= CAMEL_FOLDER_TYPE_MEMOS;
				break;
			default:
				break;
			}

			if (camel_ews_store_summary_has_folder (store->summary, fid->id)) {
				guint64 fflags = camel_ews_store_summary_get_folder_flags (store->summary, fid->id, NULL);

				if ((fflags & CAMEL_FOLDER_SUBSCRIBED) != 0)
					fi->flags |= CAMEL_FOLDER_SUBSCRIBED;
			}

			if (!(fi->flags & CAMEL_FOLDER_SUBSCRIBED) &&
			    e_ews_folder_get_folder_type (folder) != E_EWS_FOLDER_TYPE_MAILBOX) {
				if (!hosturl && !username && !esources) {
					CamelSession *session;
					CamelSettings *settings;
					CamelEwsSettings *ews_settings;
					ESourceRegistry *registry = NULL;

					settings = camel_service_ref_settings (CAMEL_SERVICE (store));
					ews_settings = CAMEL_EWS_SETTINGS (settings);
					session = camel_service_ref_session (CAMEL_SERVICE (store));
					if (E_IS_MAIL_SESSION (session))
						registry = e_mail_session_get_registry (E_MAIL_SESSION (session));

					hosturl = camel_ews_settings_dup_hosturl (ews_settings);
					username = camel_network_settings_dup_user (CAMEL_NETWORK_SETTINGS (ews_settings));
					esources = e_ews_folder_utils_get_esources (registry, hosturl, username, cancellable, NULL);

					g_object_unref (settings);
					g_object_unref (session);
				}

				if (e_ews_folder_utils_is_subscribed_as_esource (esources, hosturl, username, fid->id))
					fi->flags |= CAMEL_FOLDER_SUBSCRIBED;
			}

			g_ptr_array_add (folder_infos, fi);
		}

		g_list_free_full (esources, g_object_unref);
		g_hash_table_destroy (folders_by_id);
		g_free (hosturl);
		g_free (username);
		g_mutex_unlock (&store->priv->get_finfo_lock);

	/* search in regular/subscribed folders */
	} else {
		GSList *folders, *fiter;
		gchar *mailroot_fid = NULL, *inbox_fid;

		ews_summary = store->summary;
		folders = camel_ews_store_summary_get_folders (ews_summary, top);
		if (!folders)
			return NULL;

		inbox_fid = camel_ews_store_summary_get_folder_id_from_folder_type (ews_summary, CAMEL_FOLDER_TYPE_INBOX);
		if (inbox_fid) {
			mailroot_fid = camel_ews_store_summary_get_parent_folder_id (ews_summary, inbox_fid, NULL);
		}
		g_free (inbox_fid);
		inbox_fid = NULL;

		folder_infos = g_ptr_array_new ();

		for (fiter = folders; fiter != NULL; fiter = g_slist_next (fiter)) {
			EEwsFolderType ftype;
			const gchar *fid = fiter->data;

			ftype = camel_ews_store_summary_get_folder_type (ews_summary, fid, NULL);
			if (ftype != E_EWS_FOLDER_TYPE_MAILBOX)
				continue;

			if (camel_ews_store_summary_get_public (ews_summary, fid, NULL)) {
				guint64 fflags;

				fflags = camel_ews_store_summary_get_folder_flags (ews_summary, fid, NULL);
				if (!(fflags & CAMEL_FOLDER_SUBSCRIBED))
					continue;
			} else if (!camel_ews_store_summary_get_foreign (ews_summary, fid, NULL) &&
				mailroot_fid && !ews_store_has_as_parent_id (ews_summary, fid, mailroot_fid)) {
				/* Skip mail folders out of the msgfolderroot hierarchy */
				continue;
			}

			fi = camel_ews_utils_build_folder_info (store, fid);
			g_ptr_array_add (folder_infos, fi);
		}

		g_slist_free_full (folders, g_free);
		g_free (mailroot_fid);
	}

	root_fi = camel_folder_info_build (folder_infos, top, '/', TRUE);
	g_ptr_array_free (folder_infos, TRUE);

	return root_fi;
}