bool AbiCollabSessionManager::registerAccountHandlers()
{
	UT_DEBUGMSG(("AbiCollabSessionManager::registerAccountHandlers()\n"));

#ifdef ABICOLLAB_HANDLER_TELEPATHY
	UT_DEBUGMSG(("Registering the telepathy account handler!\n"));
	AccountHandler* pTelepathyHandler = new TelepathyAccountHandler();
	addAccount(pTelepathyHandler);
	// TODO: check if we really want to auto-connect this account
	pTelepathyHandler->connect();
#endif
#ifdef ABICOLLAB_HANDLER_XMPP
	m_regAccountHandlers[XMPPAccountHandler::getStaticStorageType()] = XMPPAccountHandlerConstructor;
#endif
#ifdef ABICOLLAB_HANDLER_TCP
	m_regAccountHandlers[TCPAccountHandler::getStaticStorageType()] = TCPAccountHandlerConstructor;
#endif
#ifdef ABICOLLAB_HANDLER_SUGAR
	// we don't want to register a sugar account handler here so
	// we can construct multiple sugar account handlers later: the 
	// sugar account handler is a singleton, that should always
	// be active if it is compiled in
	UT_DEBUGMSG(("Registering the sugar account handler!\n"));
	AccountHandler* pSugarHandler = new SugarAccountHandler();
	addAccount(pSugarHandler);
#endif
#ifdef ABICOLLAB_HANDLER_SERVICE
	if (tls_tunnel::Proxy::tls_tunnel_init())
		m_regAccountHandlers[ServiceAccountHandler::getStaticStorageType()] = ServiceAccountHandlerConstructor;
	IE_Imp_AbiCollabSniffer* pAbiCollabSniffer = new IE_Imp_AbiCollabSniffer();
	IE_Imp::registerImporter(pAbiCollabSniffer);
	m_vImpSniffers.push_back(pAbiCollabSniffer);
#endif
#ifdef ABICOLLAB_HANDLER_SIPSIMPLE
	m_regAccountHandlers[SIPSimpleAccountHandler::getStaticStorageType()] = SIPSimpleAccountHandlerConstructor;
#endif
#ifdef ABICOLLAB_HANDLER_FAKE
	AccountHandler *pFakeHandler = new FakeAccountHandler("FakeAbiCollabBackend", NULL);
	addAccount(pFakeHandler);
#endif
	return true;
}
void AbiCollabSessionManager::loadProfile()
{
	UT_DEBUGMSG(("AbiCollabSessionManager::loadProfile()\n"));

	gchar *s = g_build_filename(XAP_App::getApp()->getUserPrivateDirectory(), 
								"AbiCollab.Profile", (void*)0);
	UT_UTF8String profile(s);
	FREEP(s);

	GsfInput* in = NULL;
	char *uri = UT_go_filename_to_uri(profile.utf8_str());
	UT_return_if_fail(uri);

	in = UT_go_file_open(uri, NULL); // TODO: shouldn't use NULL here, but check for errors
	FREEP(uri);
	if (!in)
		return;

	guint8 const* contents = gsf_input_read(in, gsf_input_size(in), NULL);
	if (contents)
	{
		xmlDocPtr reader = xmlReadMemory(reinterpret_cast<const char*>(contents), 
							strlen(reinterpret_cast<const char*>(contents)), 0, "UTF-8", 0);
		if (reader)
		{
			xmlNode* node = xmlDocGetRootElement(reader);
			if (node)
			{
				if (strcmp(reinterpret_cast<const char*>(node->name), "AbiCollabProfile") == 0)
				{
					for (xmlNode* accountNode = node->children; accountNode; accountNode = accountNode->next)
					{
						// TODO: check if this node is really an AccountHandler node

						// find the account handler belonging to this type
						xmlChar* prop = xmlGetProp(accountNode, BAD_CAST "type");
						UT_UTF8String handlerType = reinterpret_cast<char *>(prop); 
						xmlFree(prop);
						std::map<UT_UTF8String, AccountHandlerConstructor>::iterator handler_iter = m_regAccountHandlers.find(handlerType);
						if (handler_iter == m_regAccountHandlers.end())
						    continue; // could happen for example when the sugar backend is found in the profile, which does not have a registered account handler belowing to it for now
						
						AccountHandlerConstructor constructor = handler_iter->second;
						AccountHandler* pHandler = constructor();
						UT_continue_if_fail(pHandler);

						for (xmlNode* accountProp = accountNode->children; accountProp; accountProp = accountProp->next)
						{
							if (accountProp->type == XML_ELEMENT_NODE)
							{
								// some node names are pre-defined...
								if (strcmp(reinterpret_cast<const char*>(accountProp->name), "buddies") == 0)
								{
									for (xmlNode* buddyNode = accountProp->children; buddyNode; buddyNode = buddyNode->next)
									{
										if (buddyNode->type != XML_ELEMENT_NODE)
										    continue;
										UT_continue_if_fail(strcmp(reinterpret_cast<const char*>(buddyNode->name), "buddy") == 0);
										UT_continue_if_fail(buddyNode->children);
										
										// read all buddy properties
										PropertyMap vBuddyProps;
										for (xmlNode* buddyPropertyNode = buddyNode->children; buddyPropertyNode; buddyPropertyNode = buddyPropertyNode->next)
										{
											UT_continue_if_fail(buddyPropertyNode->type == XML_ELEMENT_NODE);
											
											UT_UTF8String buddyPropValue = reinterpret_cast<const char*>(xmlNodeGetContent(buddyPropertyNode));
											UT_continue_if_fail(buddyPropertyNode->name && *buddyPropertyNode->name && buddyPropValue.size() > 0);
											
											vBuddyProps.insert(PropertyMap::value_type(
													reinterpret_cast<const char*>(buddyPropertyNode->name), 
													buddyPropValue.utf8_str())
												);
										}
										
										// construct the buddy	
										BuddyPtr pBuddy = pHandler->constructBuddy(vBuddyProps);
										if (pBuddy)
										{
											// add the buddy to the account handler
											pHandler->addBuddy(pBuddy);
										}
									}
								}
								else
								{
									// ... the rest are generic properties
									UT_UTF8String propValue = reinterpret_cast<const char*>(xmlNodeGetContent(accountProp));
									pHandler->addProperty(reinterpret_cast<const char*>(accountProp->name), propValue.utf8_str());
								}
							}
						}

						// add the account to the account list if it is not a duplicate
						if (addAccount(pHandler))
						{
							if (pHandler->autoConnect())
								pHandler->connect();
						}
						else
						{
							_deleteAccount(pHandler);
						}
					}
				}
			}
			xmlFreeDoc(reader);
		}
	}
	g_object_unref(G_OBJECT(in));
}