From 7f1bcf974efac0ed87b6f8f639e1fdc16a89eb09 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Fri, 27 Aug 2010 22:19:14 +0200
Subject: Separate MUCRegistry from ChatsManager.


diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp
index 921cc6f..dfe75d6 100644
--- a/Swift/Controllers/Chat/ChatsManager.cpp
+++ b/Swift/Controllers/Chat/ChatsManager.cpp
@@ -28,7 +28,7 @@ namespace Swift {
 typedef std::pair<JID, ChatController*> JIDChatControllerPair;
 typedef std::pair<JID, MUCController*> JIDMUCControllerPair;
 
-ChatsManager::ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, boost::shared_ptr<DiscoInfo> serverDiscoInfo, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency, TimerFactory* timerFactory) : jid_(jid), useDelayForLatency_(useDelayForLatency) {
+ChatsManager::ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, boost::shared_ptr<DiscoInfo> serverDiscoInfo, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency, TimerFactory* timerFactory, MUCRegistry* mucRegistry) : jid_(jid), useDelayForLatency_(useDelayForLatency), mucRegistry_(mucRegistry) {
 	timerFactory_ = timerFactory;
 	eventController_ = eventController;
 	stanzaChannel_ = stanzaChannel;
@@ -75,6 +75,7 @@ void ChatsManager::handleUserLeftMUC(MUCController* mucController) {
 	std::map<JID, MUCController*>::iterator it;
 	for (it = mucControllers_.begin(); it != mucControllers_.end(); it++) {
 		if ((*it).second == mucController) {
+			mucRegistry_->removeMUC(it->first);
 			mucControllers_.erase(it);
 			delete mucController;
 			return;
@@ -114,7 +115,7 @@ void ChatsManager::handleUIEvent(boost::shared_ptr<UIEvent> event) {
  * If a resource goes offline, release bound chatdialog to that resource.
  */
 void ChatsManager::handlePresenceChange(boost::shared_ptr<Presence> newPresence, boost::shared_ptr<Presence> /*lastPresence*/) {
-	if (isMUC(newPresence->getFrom().toBare())) return;
+	if (mucRegistry_->isMUC(newPresence->getFrom().toBare())) return;
 	if (newPresence->getType() != Presence::Unavailable) return;
 	JID fullJID(newPresence->getFrom());
 	std::map<JID, ChatController*>::iterator it = chatControllers_.find(fullJID);
@@ -162,7 +163,7 @@ void ChatsManager::handleChatRequest(const String &contact) {
 
 ChatController* ChatsManager::getChatControllerOrFindAnother(const JID &contact) {
 	ChatController* controller = getChatControllerIfExists(contact);
-	if (!controller && !isMUC(contact.toBare())) {
+	if (!controller && !mucRegistry_->isMUC(contact.toBare())) {
 		foreach (JIDChatControllerPair pair, chatControllers_) {
 			if (pair.first.toBare() == contact.toBare()) {
 				controller = pair.second;
@@ -174,7 +175,7 @@ ChatController* ChatsManager::getChatControllerOrFindAnother(const JID &contact)
 }
 
 ChatController* ChatsManager::createNewChatController(const JID& contact) {
-	ChatController* controller = new ChatController(jid_, stanzaChannel_, iqRouter_, chatWindowFactory_, contact, nickResolver_, presenceOracle_, avatarManager_, isMUC(contact.toBare()), useDelayForLatency_, uiEventStream_, eventController_);
+	ChatController* controller = new ChatController(jid_, stanzaChannel_, iqRouter_, chatWindowFactory_, contact, nickResolver_, presenceOracle_, avatarManager_, mucRegistry_->isMUC(contact.toBare()), useDelayForLatency_, uiEventStream_, eventController_);
 	chatControllers_[contact] = controller;
 	controller->setAvailableServerFeatures(serverDiscoInfo_);
 	return controller;
@@ -214,6 +215,7 @@ void ChatsManager::handleJoinMUCRequest(const JID &muc, const boost::optional<St
 		mucControllers_[muc] = controller;
 		controller->setAvailableServerFeatures(serverDiscoInfo_);
 		controller->onUserLeft.connect(boost::bind(&ChatsManager::handleUserLeftMUC, this, controller));
+		mucRegistry_->addMUC(muc);
 	}
 	mucControllers_[muc]->activateChatWindow();
 }
@@ -242,10 +244,4 @@ void ChatsManager::handleIncomingMessage(boost::shared_ptr<Message> message) {
 	getChatControllerOrCreate(jid)->handleIncomingMessage(event);
 }
 
-bool ChatsManager::isMUC(const JID& jid) const {
-	return mucControllers_.find(jid.toBare()) != mucControllers_.end();
-}
-
-
-
 }
diff --git a/Swift/Controllers/Chat/ChatsManager.h b/Swift/Controllers/Chat/ChatsManager.h
index 9af7a70..d7a6275 100644
--- a/Swift/Controllers/Chat/ChatsManager.h
+++ b/Swift/Controllers/Chat/ChatsManager.h
@@ -35,15 +35,14 @@ namespace Swift {
 	class ChatListWindowFactory;
 	class TimerFactory;
 
-	class ChatsManager : public MUCRegistry {
+	class ChatsManager {
 		public:
-			ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, boost::shared_ptr<DiscoInfo> serverDiscoInfo, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency, TimerFactory* timerFactory);
-			~ChatsManager();
+			ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, boost::shared_ptr<DiscoInfo> serverDiscoInfo, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency, TimerFactory* timerFactory, MUCRegistry* mucRegistry);
+			virtual ~ChatsManager();
 			void setAvatarManager(AvatarManager* avatarManager);
 			void setEnabled(bool enabled);
 			void setServerDiscoInfo(boost::shared_ptr<DiscoInfo> info);
 			void handleIncomingMessage(boost::shared_ptr<Message> message);
-			virtual bool isMUC(const JID& muc) const;
 		private:
 			void handleChatRequest(const String& contact);
 			void handleJoinMUCRequest(const JID& muc, const boost::optional<String>& nick);
@@ -75,5 +74,6 @@ namespace Swift {
 			boost::bsignals::scoped_connection uiEventConnection_;
 			bool useDelayForLatency_;
 			TimerFactory* timerFactory_;
+			MUCRegistry* mucRegistry_;
 	};
 }
diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
index 1676403..4b95948 100644
--- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
@@ -60,14 +60,15 @@ public:
 		eventController_ = new EventController();
 		chatWindowFactory_ = mocks_->InterfaceMock<ChatWindowFactory>();
 		xmppRoster_ = boost::shared_ptr<XMPPRoster>(new XMPPRoster());
-		nickResolver_ = new NickResolver(jid_.toBare(), xmppRoster_, NULL);
+		mucRegistry_ = new MUCRegistry();
+		nickResolver_ = new NickResolver(jid_.toBare(), xmppRoster_, NULL, mucRegistry_);
 		presenceOracle_ = new PresenceOracle(stanzaChannel_);
 		serverDiscoInfo_ = boost::shared_ptr<DiscoInfo>(new DiscoInfo());
 		presenceSender_ = new PresenceSender(stanzaChannel_);
 		uiEventStream_ = new UIEventStream();
 		chatListWindowFactory_ = mocks_->InterfaceMock<ChatListWindowFactory>();
 		mocks_->ExpectCall(chatListWindowFactory_, ChatListWindowFactory::createWindow).With(uiEventStream_).Return(NULL);
-		manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, nickResolver_, presenceOracle_, serverDiscoInfo_, presenceSender_, uiEventStream_, chatListWindowFactory_, true, NULL);
+		manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, nickResolver_, presenceOracle_, serverDiscoInfo_, presenceSender_, uiEventStream_, chatListWindowFactory_, true, NULL, mucRegistry_);
 
 		vcardStorage_ = new VCardMemoryStorage();
 		vcardManager_ = new VCardManager(jid_, iqRouter_, vcardStorage_);
@@ -85,6 +86,7 @@ public:
 		delete presenceSender_;
 		delete presenceOracle_;
 		delete nickResolver_;
+		delete mucRegistry_;
 		delete stanzaChannel_;
 		delete eventController_;
 		delete iqChannel_;
@@ -323,6 +325,7 @@ private:
 	MockRepository* mocks_;
 	UIEventStream* uiEventStream_;
 	ChatListWindowFactory* chatListWindowFactory_;
+	MUCRegistry* mucRegistry_;
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(ChatsManagerTest);
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index b94022e..d742656 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -95,6 +95,7 @@ MainController::MainController(
 	eventController_ = NULL;
 	eventWindowController_ = NULL;
 	nickResolver_ = NULL;
+	mucRegistry_ = NULL;
 	avatarManager_ = NULL;
 	vcardManager_ = NULL;
 	rosterController_ = NULL;
@@ -201,6 +202,8 @@ void MainController::resetClient() {
 	statusTracker_ = NULL;
 	delete profileSettings_;
 	profileSettings_ = NULL;
+	delete mucRegistry_;
+	mucRegistry_ = NULL;
 }
 
 void MainController::resetPendingReconnects() {
@@ -228,24 +231,21 @@ void MainController::handleConnected() {
 		serverDiscoInfo_ = boost::shared_ptr<DiscoInfo>(new DiscoInfo());
 		xmppRoster_ = boost::shared_ptr<XMPPRoster>(new XMPPRoster());
 		presenceOracle_ = new PresenceOracle(client_);
-
+		mucRegistry_ = new MUCRegistry();
 		vcardManager_ = new VCardManager(jid_, client_, getVCardStorageForProfile(jid_));
-		vcardManager_->onOwnVCardChanged.connect(boost::bind(&MainController::handleOwnVCardReceived, this, _1));
-		avatarManager_ = new AvatarManager(vcardManager_, client_, avatarStorage_);
+		vcardManager_->onVCardChanged.connect(boost::bind(&MainController::handleVCardReceived, this, _1, _2));
+		avatarManager_ = new AvatarManager(vcardManager_, client_, avatarStorage_, mucRegistry_);
 
-		nickResolver_ = new NickResolver(this->jid_.toBare(), xmppRoster_, vcardManager_);
+		nickResolver_ = new NickResolver(this->jid_.toBare(), xmppRoster_, vcardManager_, mucRegistry_);
 
 		rosterController_ = new RosterController(jid_, xmppRoster_, avatarManager_, mainWindowFactory_, nickResolver_, presenceOracle_, eventController_, uiEventStream_, client_);
 		rosterController_->onChangeStatusRequest.connect(boost::bind(&MainController::handleChangeStatusRequest, this, _1, _2));
 		rosterController_->onSignOutRequest.connect(boost::bind(&MainController::signOut, this));
 
-		chatsManager_ = new ChatsManager(jid_, client_, client_, eventController_, chatWindowFactory_, nickResolver_, presenceOracle_, serverDiscoInfo_, presenceSender_, uiEventStream_, chatListWindowFactory_, useDelayForLatency_, &timerFactory_);
-		nickResolver_->setMUCRegistry(chatsManager_);
+		chatsManager_ = new ChatsManager(jid_, client_, client_, eventController_, chatWindowFactory_, nickResolver_, presenceOracle_, serverDiscoInfo_, presenceSender_, uiEventStream_, chatListWindowFactory_, useDelayForLatency_, &timerFactory_, mucRegistry_);
 		client_->onMessageReceived.connect(boost::bind(&ChatsManager::handleIncomingMessage, chatsManager_, _1));
 		chatsManager_->setAvatarManager(avatarManager_);
 
-		avatarManager_->setMUCRegistry(chatsManager_);
-
 		xmppRosterController_ = new XMPPRosterController(client_, xmppRoster_);
 
 		eventWindowController_ = new EventWindowController(eventController_, eventWindowFactory_);
@@ -488,8 +488,8 @@ void MainController::handleServerDiscoInfoResponse(boost::shared_ptr<DiscoInfo>
 	}
 }
 
-void MainController::handleOwnVCardReceived(VCard::ref vCard) {
-	if (!vCard || vCard->getPhoto().isEmpty()) {
+void MainController::handleVCardReceived(const JID& jid, VCard::ref vCard) {
+	if (!jid.equals(jid_, JID::WithoutResource) || !vCard || vCard->getPhoto().isEmpty()) {
 		return;
 	}
 	vCardPhotoHash_ = Hexify::hexify(SHA1::getHash(vCard->getPhoto()));
diff --git a/Swift/Controllers/MainController.h b/Swift/Controllers/MainController.h
index cf04e59..ef9c79e 100644
--- a/Swift/Controllers/MainController.h
+++ b/Swift/Controllers/MainController.h
@@ -66,6 +66,7 @@ namespace Swift {
 	class MUCSearchWindowFactory;
 	class StatusTracker;
 	class VCardStorageFactory;
+	class MUCRegistry;
 
 	class MainController {
 		public:
@@ -96,7 +97,7 @@ namespace Swift {
 			void handleError(const ClientError& error);
 			void handleServerDiscoInfoResponse(boost::shared_ptr<DiscoInfo>, const boost::optional<ErrorPayload>&);
 			void handleEventQueueLengthChange(int count);
-			void handleOwnVCardReceived(VCard::ref vCard);
+			void handleVCardReceived(const JID& j, VCard::ref vCard);
 			void sendPresence(boost::shared_ptr<Presence> presence);
 			void handleInputIdleChanged(bool);
 			void logout();
@@ -159,6 +160,7 @@ namespace Swift {
 			int timeBeforeNextReconnect_;
 			Timer::ref reconnectTimer_;
 			StatusTracker* statusTracker_;
+			MUCRegistry* mucRegistry_;
 
 			typedef std::map<String, VCardStorage*> VCardStorageMap;
 			VCardStorageMap vcardStorages_;
diff --git a/Swift/Controllers/NickResolver.cpp b/Swift/Controllers/NickResolver.cpp
index 1d2a3a0..b6fefe3 100644
--- a/Swift/Controllers/NickResolver.cpp
+++ b/Swift/Controllers/NickResolver.cpp
@@ -15,18 +15,14 @@
 
 namespace Swift {
 
-NickResolver::NickResolver(const JID& ownJID, boost::shared_ptr<XMPPRoster> xmppRoster, VCardManager* vcardManager) : ownJID_(ownJID) {
+NickResolver::NickResolver(const JID& ownJID, boost::shared_ptr<XMPPRoster> xmppRoster, VCardManager* vcardManager, MUCRegistry* mucRegistry) : ownJID_(ownJID) {
 	xmppRoster_ = xmppRoster;
 	vcardManager_ = vcardManager;
 	if (vcardManager_) {
-		vcardManager_->onOwnVCardChanged.connect(boost::bind(&NickResolver::handleOwnVCardReceived, this, _1));
+		vcardManager_->onVCardChanged.connect(boost::bind(&NickResolver::handleVCardReceived, this, _1, _2));
 		VCard::ref ownVCard = vcardManager_->getVCardAndRequestWhenNeeded(ownJID_);
-		handleOwnVCardReceived(ownVCard);
+		handleVCardReceived(ownJID_, ownVCard);
 	}
-	mucRegistry_ = NULL;
-}
-
-void NickResolver::setMUCRegistry(MUCRegistry* mucRegistry) {
 	mucRegistry_ = mucRegistry;
 }
 
@@ -50,7 +46,10 @@ String NickResolver::jidToNick(const JID& jid) {
 	return (it == map_.end()) ? jid.toBare() : it->second;
 }
 
-void NickResolver::handleOwnVCardReceived(VCard::ref ownVCard) {
+void NickResolver::handleVCardReceived(const JID& jid, VCard::ref ownVCard) {
+	if (!jid.equals(ownJID_, JID::WithoutResource)) {
+		return;
+	}
 	String initialNick = ownNick_;
 	ownNick_ = ownJID_.toString();
 	if (ownVCard) {
diff --git a/Swift/Controllers/NickResolver.h b/Swift/Controllers/NickResolver.h
index 4abb71d..24081b2 100644
--- a/Swift/Controllers/NickResolver.h
+++ b/Swift/Controllers/NickResolver.h
@@ -21,13 +21,14 @@ namespace Swift {
 	class VCardManager;
 	class NickResolver {
 		public:
-			NickResolver(const JID& ownJID, boost::shared_ptr<XMPPRoster> xmppRoster, VCardManager* vcardManager);
+			NickResolver(const JID& ownJID, boost::shared_ptr<XMPPRoster> xmppRoster, VCardManager* vcardManager, MUCRegistry* mucRegistry);
+
 			String jidToNick(const JID& jid);
 			void setMUCRegistry(MUCRegistry* registry);
 
 			boost::signal<void (const String&)> onOwnNickChanged;
 		private:
-			void handleOwnVCardReceived(VCard::ref vCard);
+			void handleVCardReceived(const JID& jid, VCard::ref vCard);
 			JID ownJID_;
 			String ownNick_;
 			std::map<JID, String> map_;
diff --git a/Swift/Controllers/UnitTest/MockMUCRegistry.h b/Swift/Controllers/UnitTest/MockMUCRegistry.h
deleted file mode 100644
index fdda8e1..0000000
--- a/Swift/Controllers/UnitTest/MockMUCRegistry.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2010 Kevin Smith
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#pragma once
-
-#include "Swiften/MUC/MUCRegistry.h"
-
-namespace Swift {
-	class JID;
-
-	class MockMUCRegistry : public MUCRegistry {
-		public:
-			virtual ~MockMUCRegistry() {};
-
-			void setNext(bool next) {next_ = next;}
-			virtual bool isMUC(const JID&) const {return next_;}
-
-		private:
-			bool next_;
-	};
-}
diff --git a/Swift/Controllers/UnitTest/NickResolverTest.cpp b/Swift/Controllers/UnitTest/NickResolverTest.cpp
index 67b42ac..dfb459f 100644
--- a/Swift/Controllers/UnitTest/NickResolverTest.cpp
+++ b/Swift/Controllers/UnitTest/NickResolverTest.cpp
@@ -8,7 +8,7 @@
 #include <cppunit/extensions/TestFactoryRegistry.h>
 
 #include "Swift/Controllers/NickResolver.h"
-#include "Swift/Controllers/UnitTest/MockMUCRegistry.h"
+#include "Swiften/MUC/MUCRegistry.h"
 #include "Swiften/Roster/XMPPRoster.h"
 #include "Swiften/VCards/VCardManager.h"
 #include "Swiften/VCards/VCardMemoryStorage.h"
@@ -17,8 +17,7 @@
 
 using namespace Swift;
 
-class NickResolverTest : public CppUnit::TestFixture
-{
+class NickResolverTest : public CppUnit::TestFixture {
 		CPPUNIT_TEST_SUITE(NickResolverTest);
 		CPPUNIT_TEST(testNoMatch);
 		CPPUNIT_TEST(testZeroLengthMatch);
@@ -33,18 +32,7 @@ class NickResolverTest : public CppUnit::TestFixture
 		CPPUNIT_TEST(testOwnNickNickEtAl);
 		CPPUNIT_TEST_SUITE_END();
 
-		std::vector<String> groups_;
-		boost::shared_ptr<XMPPRoster> xmppRoster_;
-		VCardStorage* vCardStorage_;
-		IQRouter* iqRouter_;
-		DummyStanzaChannel* stanzaChannel_;
-		VCardManager* vCardManager_;
-		NickResolver* resolver_;
-		JID ownJID_;
-
 	public:
-		NickResolverTest() {}
-
 		void setUp() {
 			ownJID_ = JID("kev@wonderland.lit");
 			xmppRoster_ = boost::shared_ptr<XMPPRoster>(new XMPPRoster());
@@ -52,30 +40,28 @@ class NickResolverTest : public CppUnit::TestFixture
 		  iqRouter_ = new IQRouter(stanzaChannel_);
 			vCardStorage_ = new VCardMemoryStorage();
 			vCardManager_ = new VCardManager(ownJID_, iqRouter_, vCardStorage_);
-			resolver_ = new NickResolver(ownJID_, xmppRoster_, vCardManager_);
+			registry_ = new MUCRegistry();
+			resolver_ = new NickResolver(ownJID_, xmppRoster_, vCardManager_, registry_);
 		}
 
 		void tearDown() {
+			delete resolver_;
+			delete registry_;
 			delete vCardManager_;
 			delete stanzaChannel_;
 			delete iqRouter_;
 			delete vCardStorage_;
-			delete resolver_;
 		}
 
 		void testMUCNick() {
-			MockMUCRegistry registry;
-			resolver_->setMUCRegistry(&registry);
-			registry.setNext(true);
+			registry_->addMUC(JID("foo@bar"));
 			JID testJID("foo@bar/baz");
 
 			CPPUNIT_ASSERT_EQUAL(String("baz"), resolver_->jidToNick(testJID));
 		}
 
 		void testMUCNoNick() {
-			MockMUCRegistry registry;
-			resolver_->setMUCRegistry(&registry);
-			registry.setNext(true);
+			registry_->addMUC(JID("foo@bar"));
 			JID testJID("foo@bar");
 
 			CPPUNIT_ASSERT_EQUAL(String("foo@bar"), resolver_->jidToNick(testJID));
@@ -146,6 +132,18 @@ class NickResolverTest : public CppUnit::TestFixture
 			IQ::ref result(IQ::createResult(JID(), stanzaChannel_->sentStanzas[0]->getID(), vcard));
 			stanzaChannel_->onIQReceived(result);
 		}
+	
+	private:
+		std::vector<String> groups_;
+		boost::shared_ptr<XMPPRoster> xmppRoster_;
+		VCardStorage* vCardStorage_;
+		IQRouter* iqRouter_;
+		DummyStanzaChannel* stanzaChannel_;
+		VCardManager* vCardManager_;
+		MUCRegistry* registry_;
+		NickResolver* resolver_;
+		JID ownJID_;
+
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(NickResolverTest);
diff --git a/Swift/Controllers/UnitTest/RosterControllerTest.cpp b/Swift/Controllers/UnitTest/RosterControllerTest.cpp
index f57240f..23fca2c 100644
--- a/Swift/Controllers/UnitTest/RosterControllerTest.cpp
+++ b/Swift/Controllers/UnitTest/RosterControllerTest.cpp
@@ -24,6 +24,7 @@
 #include "Swiften/Presence/PresenceOracle.h"
 #include "Swift/Controllers/NickResolver.h"
 #include "Swift/Controllers/UIEvents/UIEventStream.h"
+#include "Swiften/MUC/MUCRegistry.h"
 
 using namespace Swift;
 
@@ -44,7 +45,8 @@ class RosterControllerTest : public CppUnit::TestFixture
 			xmppRoster_ = boost::shared_ptr<XMPPRoster>(new XMPPRoster());
 			avatarManager_ = NULL;//new AvatarManager();
 			mainWindowFactory_ = new MockMainWindowFactory();
-			nickResolver_ = new NickResolver(jid_.toBare(), xmppRoster_, NULL);
+			mucRegistry_ = new MUCRegistry();
+			nickResolver_ = new NickResolver(jid_.toBare(), xmppRoster_, NULL, mucRegistry_);
 			channel_ = new DummyIQChannel();
 			router_ = new IQRouter(channel_);
 			stanzaChannel_ = new DummyStanzaChannel();
@@ -58,6 +60,7 @@ class RosterControllerTest : public CppUnit::TestFixture
 		void tearDown() {
 			delete rosterController_;
 			delete nickResolver_;
+			delete mucRegistry_;
 			delete mainWindowFactory_;
 			delete avatarManager_;
 			delete channel_;
@@ -116,6 +119,7 @@ class RosterControllerTest : public CppUnit::TestFixture
 	private:
 		JID jid_;
 		boost::shared_ptr<XMPPRoster> xmppRoster_;
+		MUCRegistry* mucRegistry_;
 		AvatarManager* avatarManager_;
 		MockMainWindowFactory* mainWindowFactory_;
 		NickResolver* nickResolver_;
diff --git a/Swiften/Avatars/AvatarManager.cpp b/Swiften/Avatars/AvatarManager.cpp
index 909b07c..cd691c0 100644
--- a/Swiften/Avatars/AvatarManager.cpp
+++ b/Swiften/Avatars/AvatarManager.cpp
@@ -21,10 +21,6 @@ AvatarManager::~AvatarManager() {
 	delete vcardUpdateAvatarManager;
 }
 
-void AvatarManager::setMUCRegistry(MUCRegistry* mucRegistry) {
-	vcardUpdateAvatarManager->setMUCRegistry(mucRegistry);
-}
-
 boost::filesystem::path AvatarManager::getAvatarPath(const JID& jid) const {
 	return vcardUpdateAvatarManager->getAvatarPath(jid);
 }
diff --git a/Swiften/Avatars/AvatarManager.h b/Swiften/Avatars/AvatarManager.h
index d3d593d..90f0076 100644
--- a/Swiften/Avatars/AvatarManager.h
+++ b/Swiften/Avatars/AvatarManager.h
@@ -29,8 +29,6 @@ namespace Swift {
 			AvatarManager(VCardManager*, StanzaChannel*, AvatarStorage*, MUCRegistry* = NULL);
 			virtual ~AvatarManager();
 
-			virtual void setMUCRegistry(MUCRegistry*);
-
 			virtual boost::filesystem::path getAvatarPath(const JID&) const;
 
 		public:
diff --git a/Swiften/Avatars/VCardUpdateAvatarManager.cpp b/Swiften/Avatars/VCardUpdateAvatarManager.cpp
index c7f1637..80d7730 100644
--- a/Swiften/Avatars/VCardUpdateAvatarManager.cpp
+++ b/Swiften/Avatars/VCardUpdateAvatarManager.cpp
@@ -28,10 +28,6 @@ VCardUpdateAvatarManager::~VCardUpdateAvatarManager() {
 
 }
 
-void VCardUpdateAvatarManager::setMUCRegistry(MUCRegistry* mucRegistry) {
-	mucRegistry_ = mucRegistry;
-}
-
 void VCardUpdateAvatarManager::handlePresenceReceived(boost::shared_ptr<Presence> presence) {
 	boost::shared_ptr<VCardUpdate> update = presence->getPayload<VCardUpdate>();
 	if (!update || presence->getPayload<ErrorPayload>()) {
diff --git a/Swiften/Avatars/VCardUpdateAvatarManager.h b/Swiften/Avatars/VCardUpdateAvatarManager.h
index b7ef34b..16c0ca3 100644
--- a/Swiften/Avatars/VCardUpdateAvatarManager.h
+++ b/Swiften/Avatars/VCardUpdateAvatarManager.h
@@ -28,8 +28,6 @@ namespace Swift {
 			VCardUpdateAvatarManager(VCardManager*, StanzaChannel*, AvatarStorage*, MUCRegistry* = NULL);
 			virtual ~VCardUpdateAvatarManager();
 
-			virtual void setMUCRegistry(MUCRegistry*);
-
 			virtual boost::filesystem::path getAvatarPath(const JID&) const;
 
 		public:
diff --git a/Swiften/MUC/MUCRegistry.cpp b/Swiften/MUC/MUCRegistry.cpp
index 910d740..e433165 100644
--- a/Swiften/MUC/MUCRegistry.cpp
+++ b/Swiften/MUC/MUCRegistry.cpp
@@ -6,9 +6,24 @@
 
 #include "Swiften/MUC/MUCRegistry.h"
 
+#include <algorithm>
+
 namespace Swift {
 
 MUCRegistry::~MUCRegistry() {
 }
 
+bool MUCRegistry::isMUC(const JID& j) const {
+	return std::find(mucs.begin(), mucs.end(), j) != mucs.end();
+}
+
+void MUCRegistry::addMUC(const JID& j) {
+	mucs.push_back(j);
+}
+
+void MUCRegistry::removeMUC(const JID& j) {
+	mucs.erase(std::remove(mucs.begin(), mucs.end(), j), mucs.end());
+}
+
+
 }
diff --git a/Swiften/MUC/MUCRegistry.h b/Swiften/MUC/MUCRegistry.h
index e6f2ab6..6356931 100644
--- a/Swiften/MUC/MUCRegistry.h
+++ b/Swiften/MUC/MUCRegistry.h
@@ -6,13 +6,22 @@
 
 #pragma once
 
+#include <vector>
+
+#include "Swiften/JID/JID.h"
+
 namespace Swift {
 	class JID;
 
 	class MUCRegistry {
 		public:
-			virtual ~MUCRegistry();
+			~MUCRegistry();
+
+			bool isMUC(const JID& j) const;
+			void addMUC(const JID& j);
+			void removeMUC(const JID& j);
 
-			virtual bool isMUC(const JID&) const = 0;
+		private:
+			std::vector<JID> mucs;
 	};
 }
diff --git a/Swiften/VCards/VCardManager.h b/Swiften/VCards/VCardManager.h
index fc99128..61fc50d 100644
--- a/Swiften/VCards/VCardManager.h
+++ b/Swiften/VCards/VCardManager.h
@@ -31,7 +31,6 @@ namespace Swift {
 			 * The JID will always be bare.
 			 */
 			boost::signal<void (const JID&, VCard::ref)> onVCardChanged;
-			boost::signal<void (VCard::ref)> onOwnVCardChanged;
 
 		private:
 			void handleVCardReceived(const JID& from, VCard::ref, const boost::optional<ErrorPayload>&);
-- 
cgit v0.10.2-6-g49f6