void
JabberProtocol::ProcessPresence(XMLEntity *entity)
{
	

	int num_matches = 0;

	// verify we have a username
	if (entity->Attribute("from"))
	{
		// circumvent groupchat presences
		string room, server, user;
		
		if (entity->Child("x", "xmlns", "http://jabber.org/protocol/muc#user"))
		{
			UserID from = UserID(string(entity->Attribute("from")));
			room = from.JabberUsername();
			server = from.JabberServer();
			user = from.JabberResource();
			fprintf(stderr, "Group Presence in room %s from user %s.\n", 
				from.JabberHandle().c_str(), user.c_str());
						
			BMessage *msg = new BMessage(JAB_GROUP_CHATTER_ONLINE);
			msg->AddString("room", (room + '@' + server).c_str());
			msg->AddString("server", server.c_str());
			msg->AddString("username", user.c_str());
			
			if (!entity->Attribute("type") || !strcasecmp(entity->Attribute("type"), "available"))
			{
				if (entity->Child("show") && entity->Child("show")->Data())
				{
					msg->AddString("show", entity->Child("show")->Data());
				} else
					msg->AddString("show", "online");

				if (entity->Child("status") && entity->Child("status")->Data())
				{
					msg->AddString("status", entity->Child("status")->Data());
				} else
					msg->AddString("status", "");
				
				if (entity->Child("x")->Child("item") &&
					entity->Child("x")->Child("item")->Attribute("role"))
					msg->AddString("role", entity->Child("x")->Child("item")->Attribute("role"));
				else
					msg->AddString("role", "admin");
				
				if (entity->Child("x")->Child("item") &&
					entity->Child("x")->Child("item")->Attribute("affiliation"))
					msg->AddString("affiliation", entity->Child("x")->Child("item")->Attribute("affiliation"));
				else
					msg->AddString("affiliation", "none");
		
				msg->what = JAB_GROUP_CHATTER_ONLINE;
			}
			else if (!strcasecmp(entity->Attribute("type"), "unavailable"))
			{
				msg->what = JAB_GROUP_CHATTER_OFFLINE;
			}
			
			TalkManager::Instance()->Lock();
			
			ChatWindow *window = TalkManager::Instance()->FindWindow(from.JabberHandle());
			
			if (window != NULL)
			{
				fprintf(stderr, "Process group presence %s.\n", window->GetUserID()->JabberHandle().c_str());
				
				window->PostMessage(msg);
			}
			else
			{
				fprintf(stderr, "There is no window group presence route to.\n");
			}
			
			TalkManager::Instance()->Unlock();
			
			return;
		}		
		
		JRoster *roster = JRoster::Instance();
		
		roster->Lock();
		
		for (JRoster::ConstRosterIter i = roster->BeginIterator(); i != roster->EndIterator(); ++i)
		{
			UserID *user = NULL;

			if (!strcasecmp(UserID(entity->Attribute("from")).JabberHandle().c_str(),
					(*i)->JabberHandle().c_str()))
			{
				++num_matches;
				user = *i;
				ProcessUserPresence(user, entity);
				fprintf(stderr, "Process roster presence %s.\n", user->JabberHandle().c_str());
			}
		}
		
		if (num_matches == 0)
		{
			UserID user(string(entity->Attribute("from")));
			fprintf(stderr, "Process not in roster presence %s.\n", user.JabberHandle().c_str());
			ProcessUserPresence(&user, entity);
		}
			
		roster->Unlock();
		
		mainWindow->PostMessage(BLAB_UPDATE_ROSTER);			

	}
}