From 7af8a078c57d94ff63eb81f26de2f55eca6b5c00 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Sat, 18 Jun 2011 12:21:21 +0200
Subject: Moving unused server code out of Swiften into Limber.


diff --git a/Limber/SConscript b/Limber/SConscript
index e2fadac..bc05f7f 100644
--- a/Limber/SConscript
+++ b/Limber/SConscript
@@ -1,8 +1,26 @@
 Import("env")
 
-if env["SCONS_STAGE"] == "build" :
+if env["SCONS_STAGE"] == "flags" :
+	env["LIMBER_FLAGS"] = {
+		"LIBPATH": [Dir(".")],
+		"LIBS": ["Limber"],
+	}
+
+elif env["SCONS_STAGE"] == "build" :
+	libenv = env.Clone()
+	libenv.MergeFlags(env["BOOST_FLAGS"])
+	libenv.MergeFlags(env["SWIFTEN_FLAGS"])
+	libenv.StaticLibrary("Limber", [
+			"Server/ServerFromClientSession.cpp",
+			"Server/ServerSession.cpp",
+			"Server/ServerStanzaRouter.cpp",
+			"Server/SimpleUserRegistry.cpp",
+			"Server/UserRegistry.cpp",
+		])
+
 	myenv = env.Clone()
 	myenv.BuildVersion("BuildVersion.h", project = "limber")
+	myenv.UseFlags(env["LIMBER_FLAGS"])
 	myenv.UseFlags(env["SWIFTEN_FLAGS"])
 	myenv.UseFlags(env["LIBIDN_FLAGS"])
 	myenv.UseFlags(env.get("LIBXML_FLAGS", ""))
@@ -10,5 +28,8 @@ if env["SCONS_STAGE"] == "build" :
 	myenv.UseFlags(env["OPENSSL_FLAGS"])
 	myenv.UseFlags(env["BOOST_FLAGS"])
 	myenv.UseFlags(myenv["PLATFORM_FLAGS"])
-
 	myenv.Program("limber", ["main.cpp"])
+
+	env.Append(UNITTEST_SOURCES = [
+			File("Server/UnitTest/ServerStanzaRouterTest.cpp"),
+		])
diff --git a/Limber/Server/ServerFromClientSession.cpp b/Limber/Server/ServerFromClientSession.cpp
new file mode 100644
index 0000000..b51a53f
--- /dev/null
+++ b/Limber/Server/ServerFromClientSession.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include "Limber/Server/ServerFromClientSession.h"
+
+#include <boost/bind.hpp>
+
+#include "Swiften/Elements/ProtocolHeader.h"
+#include "Limber/Server/UserRegistry.h"
+#include "Swiften/Network/Connection.h"
+#include "Swiften/StreamStack/XMPPLayer.h"
+#include "Swiften/Elements/StreamFeatures.h"
+#include "Swiften/Elements/ResourceBind.h"
+#include "Swiften/Elements/StartSession.h"
+#include "Swiften/Elements/IQ.h"
+#include "Swiften/Elements/AuthSuccess.h"
+#include "Swiften/Elements/AuthFailure.h"
+#include "Swiften/Elements/AuthRequest.h"
+#include "Swiften/SASL/PLAINMessage.h"
+
+namespace Swift {
+
+ServerFromClientSession::ServerFromClientSession(
+		const std::string& id,
+		boost::shared_ptr<Connection> connection, 
+		PayloadParserFactoryCollection* payloadParserFactories, 
+		PayloadSerializerCollection* payloadSerializers,
+		UserRegistry* userRegistry) : 
+			Session(connection, payloadParserFactories, payloadSerializers),
+			id_(id),
+			userRegistry_(userRegistry),
+			authenticated_(false),
+			initialized(false),
+			allowSASLEXTERNAL(false) {
+}
+
+
+void ServerFromClientSession::handleElement(boost::shared_ptr<Element> element) {
+	if (isInitialized()) {
+		onElementReceived(element);
+	}
+	else {
+		if (AuthRequest* authRequest = dynamic_cast<AuthRequest*>(element.get())) {
+			if (authRequest->getMechanism() == "PLAIN" || (allowSASLEXTERNAL && authRequest->getMechanism() == "EXTERNAL")) {
+				if (authRequest->getMechanism() == "EXTERNAL") {
+						getXMPPLayer()->writeElement(boost::shared_ptr<AuthSuccess>(new AuthSuccess()));
+						authenticated_ = true;
+						getXMPPLayer()->resetParser();
+				}
+				else {
+					PLAINMessage plainMessage(authRequest->getMessage() ? *authRequest->getMessage() : "");
+					if (userRegistry_->isValidUserPassword(JID(plainMessage.getAuthenticationID(), getLocalJID().getDomain()), plainMessage.getPassword())) {
+						getXMPPLayer()->writeElement(boost::shared_ptr<AuthSuccess>(new AuthSuccess()));
+						user_ = plainMessage.getAuthenticationID();
+						authenticated_ = true;
+						getXMPPLayer()->resetParser();
+					}
+					else {
+						getXMPPLayer()->writeElement(boost::shared_ptr<AuthFailure>(new AuthFailure));
+						finishSession(AuthenticationFailedError);
+					}
+				}
+			}
+			else {
+				getXMPPLayer()->writeElement(boost::shared_ptr<AuthFailure>(new AuthFailure));
+				finishSession(NoSupportedAuthMechanismsError);
+			}
+		}
+		else if (IQ* iq = dynamic_cast<IQ*>(element.get())) {
+			if (boost::shared_ptr<ResourceBind> resourceBind = iq->getPayload<ResourceBind>()) {
+				setRemoteJID(JID(user_, getLocalJID().getDomain(), resourceBind->getResource()));
+				boost::shared_ptr<ResourceBind> resultResourceBind(new ResourceBind());
+				resultResourceBind->setJID(getRemoteJID());
+				getXMPPLayer()->writeElement(IQ::createResult(JID(), iq->getID(), resultResourceBind));
+			}
+			else if (iq->getPayload<StartSession>()) {
+				getXMPPLayer()->writeElement(IQ::createResult(getRemoteJID(), iq->getID()));
+				setInitialized();
+			}
+		}
+	}
+}
+
+void ServerFromClientSession::handleStreamStart(const ProtocolHeader& incomingHeader) {
+	setLocalJID(JID("", incomingHeader.getTo()));
+	ProtocolHeader header;
+	header.setFrom(incomingHeader.getTo());
+	header.setID(id_);
+	getXMPPLayer()->writeHeader(header);
+
+	boost::shared_ptr<StreamFeatures> features(new StreamFeatures());
+	if (!authenticated_) {
+		features->addAuthenticationMechanism("PLAIN");
+		if (allowSASLEXTERNAL) {
+			features->addAuthenticationMechanism("EXTERNAL");
+		}
+	}
+	else {
+		features->setHasResourceBind();
+		features->setHasSession();
+	}
+	getXMPPLayer()->writeElement(features);
+}
+
+void ServerFromClientSession::setInitialized() {
+	initialized = true;
+	onSessionStarted();
+}
+
+void ServerFromClientSession::setAllowSASLEXTERNAL() {
+	allowSASLEXTERNAL = true;
+}
+
+}
diff --git a/Limber/Server/ServerFromClientSession.h b/Limber/Server/ServerFromClientSession.h
new file mode 100644
index 0000000..80ef063
--- /dev/null
+++ b/Limber/Server/ServerFromClientSession.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+#include "Swiften/Base/boost_bsignals.h"
+#include <boost/enable_shared_from_this.hpp>
+
+#include <string>
+#include "Swiften/Session/Session.h"
+#include "Swiften/JID/JID.h"
+#include "Swiften/Network/Connection.h"
+
+namespace Swift {
+	class ProtocolHeader;
+	class Element;
+	class Stanza;
+	class PayloadParserFactoryCollection;
+	class PayloadSerializerCollection;
+	class StreamStack;
+	class UserRegistry;
+	class XMPPLayer;
+	class ConnectionLayer;
+	class Connection;
+	class ByteArray;
+
+	class ServerFromClientSession : public Session {
+		public:
+			ServerFromClientSession(
+					const std::string& id,
+					boost::shared_ptr<Connection> connection, 
+					PayloadParserFactoryCollection* payloadParserFactories, 
+					PayloadSerializerCollection* payloadSerializers,
+					UserRegistry* userRegistry);
+
+			boost::signal<void ()> onSessionStarted;
+			void setAllowSASLEXTERNAL();
+
+		private:
+			void handleElement(boost::shared_ptr<Element>);
+			void handleStreamStart(const ProtocolHeader& header);
+
+			void setInitialized();
+			bool isInitialized() const { 
+				return initialized; 
+			}
+
+		private:
+			std::string id_;
+			UserRegistry* userRegistry_;
+			bool authenticated_;
+			bool initialized;
+			bool allowSASLEXTERNAL;
+			std::string user_;
+	};
+}
diff --git a/Limber/Server/ServerSession.cpp b/Limber/Server/ServerSession.cpp
new file mode 100644
index 0000000..5b6d66a
--- /dev/null
+++ b/Limber/Server/ServerSession.cpp
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include "Limber/Server/ServerSession.h"
+
+namespace Swift {
+
+ServerSession::~ServerSession() {
+}
+
+}
diff --git a/Limber/Server/ServerSession.h b/Limber/Server/ServerSession.h
new file mode 100644
index 0000000..bd4ab6d
--- /dev/null
+++ b/Limber/Server/ServerSession.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+
+#include "Swiften/Elements/Stanza.h"
+
+namespace Swift {
+	class ServerSession {
+		public:
+			virtual ~ServerSession();
+
+			virtual const JID& getJID() const = 0;
+			virtual int getPriority() const = 0;
+
+			virtual void sendStanza(boost::shared_ptr<Stanza>) = 0;
+	};
+}
diff --git a/Limber/Server/ServerStanzaRouter.cpp b/Limber/Server/ServerStanzaRouter.cpp
new file mode 100644
index 0000000..fec529f
--- /dev/null
+++ b/Limber/Server/ServerStanzaRouter.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include "Limber/Server/ServerStanzaRouter.h"
+#include "Limber/Server/ServerSession.h"
+
+#include <cassert>
+#include <algorithm>
+
+namespace Swift {
+
+namespace {
+	struct PriorityLessThan {
+		bool operator()(const ServerSession* s1, const ServerSession* s2) const {
+			return s1->getPriority() < s2->getPriority();
+		}
+	};
+
+	struct HasJID {
+		HasJID(const JID& jid) : jid(jid) {}
+		bool operator()(const ServerSession* session) const {
+			return session->getJID().equals(jid, JID::WithResource);
+		}
+		JID jid;
+	};
+}
+
+ServerStanzaRouter::ServerStanzaRouter() {
+}
+
+bool ServerStanzaRouter::routeStanza(boost::shared_ptr<Stanza> stanza) {
+	JID to = stanza->getTo();
+	assert(to.isValid());
+
+	// For a full JID, first try to route to a session with the full JID
+	if (!to.isBare()) {
+		std::vector<ServerSession*>::const_iterator i = std::find_if(clientSessions_.begin(), clientSessions_.end(), HasJID(to));
+		if (i != clientSessions_.end()) {
+			(*i)->sendStanza(stanza);
+			return true;
+		}
+	}
+
+	// Look for candidate sessions
+	to = to.toBare();
+	std::vector<ServerSession*> candidateSessions;
+	for (std::vector<ServerSession*>::const_iterator i = clientSessions_.begin(); i != clientSessions_.end(); ++i) {
+		if ((*i)->getJID().equals(to, JID::WithoutResource) && (*i)->getPriority() >= 0) {
+			candidateSessions.push_back(*i);
+		}
+	}
+	if (candidateSessions.empty()) {
+		return false;
+	}
+
+	// Find the session with the highest priority
+	std::vector<ServerSession*>::const_iterator i = std::max_element(clientSessions_.begin(), clientSessions_.end(), PriorityLessThan());
+	(*i)->sendStanza(stanza);
+	return true;
+}
+
+void ServerStanzaRouter::addClientSession(ServerSession* clientSession) {
+	clientSessions_.push_back(clientSession);
+}
+
+void ServerStanzaRouter::removeClientSession(ServerSession* clientSession) {
+	clientSessions_.erase(std::remove(clientSessions_.begin(), clientSessions_.end(), clientSession), clientSessions_.end());
+}
+
+}
diff --git a/Limber/Server/ServerStanzaRouter.h b/Limber/Server/ServerStanzaRouter.h
new file mode 100644
index 0000000..2a1960c
--- /dev/null
+++ b/Limber/Server/ServerStanzaRouter.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+#include <map>
+
+#include "Swiften/JID/JID.h"
+#include "Swiften/Elements/Stanza.h"
+
+namespace Swift {
+	class ServerSession;
+
+	class ServerStanzaRouter {
+		public:
+			ServerStanzaRouter();
+
+			bool routeStanza(boost::shared_ptr<Stanza>);
+
+			void addClientSession(ServerSession*);
+			void removeClientSession(ServerSession*);
+
+		private:
+			std::vector<ServerSession*> clientSessions_;
+	};
+}
diff --git a/Limber/Server/SimpleUserRegistry.cpp b/Limber/Server/SimpleUserRegistry.cpp
new file mode 100644
index 0000000..5b7329a
--- /dev/null
+++ b/Limber/Server/SimpleUserRegistry.cpp
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include "Limber/Server/SimpleUserRegistry.h"
+
+namespace Swift {
+
+SimpleUserRegistry::SimpleUserRegistry() {
+}
+
+bool SimpleUserRegistry::isValidUserPassword(const JID& user, const std::string& password) const {
+	std::map<JID,std::string>::const_iterator i = users.find(user);
+	return i != users.end() ? i->second == password : false;
+}
+
+void SimpleUserRegistry::addUser(const JID& user, const std::string& password) {
+	users.insert(std::make_pair(user, password));
+}
+
+}
diff --git a/Limber/Server/SimpleUserRegistry.h b/Limber/Server/SimpleUserRegistry.h
new file mode 100644
index 0000000..677d006
--- /dev/null
+++ b/Limber/Server/SimpleUserRegistry.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <map>
+
+#include "Swiften/JID/JID.h"
+#include <string>
+#include "Limber/Server/UserRegistry.h"
+
+namespace Swift {
+	
+
+	class SimpleUserRegistry : public UserRegistry {
+		public:
+			SimpleUserRegistry();
+
+			virtual bool isValidUserPassword(const JID& user, const std::string& password) const;
+			void addUser(const JID& user, const std::string& password);
+
+		private:
+			std::map<JID, std::string> users;
+	};
+}
diff --git a/Limber/Server/UnitTest/ServerStanzaRouterTest.cpp b/Limber/Server/UnitTest/ServerStanzaRouterTest.cpp
new file mode 100644
index 0000000..87c713e
--- /dev/null
+++ b/Limber/Server/UnitTest/ServerStanzaRouterTest.cpp
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include "Swiften/Elements/Message.h"
+#include "Limber/Server/ServerStanzaRouter.h"
+#include "Limber/Server/ServerSession.h"
+
+using namespace Swift;
+
+class ServerStanzaRouterTest : public CppUnit::TestFixture {
+		CPPUNIT_TEST_SUITE(ServerStanzaRouterTest);
+		CPPUNIT_TEST(testRouteStanza_FullJID);
+		CPPUNIT_TEST(testRouteStanza_FullJIDWithNegativePriority);
+		CPPUNIT_TEST(testRouteStanza_FullJIDWithOnlyBareJIDMatchingSession);
+		CPPUNIT_TEST(testRouteStanza_BareJIDWithoutMatchingSession);
+		CPPUNIT_TEST(testRouteStanza_BareJIDWithMultipleSessions);
+		CPPUNIT_TEST(testRouteStanza_BareJIDWithOnlyNegativePriorities);
+		CPPUNIT_TEST(testRouteStanza_BareJIDWithChangingPresence);
+		CPPUNIT_TEST_SUITE_END();
+
+	public:
+		ServerStanzaRouterTest() {}
+
+		void setUp() {
+		}
+
+		void tearDown() {
+		}
+
+		void testRouteStanza_FullJID() {
+			ServerStanzaRouter testling;
+			MockServerSession session1(JID("foo@bar.com/Bla"), 0);
+			testling.addClientSession(&session1);
+			MockServerSession session2(JID("foo@bar.com/Baz"), 0);
+			testling.addClientSession(&session2);
+
+			bool result = testling.routeStanza(createMessageTo("foo@bar.com/Baz"));
+
+			CPPUNIT_ASSERT(result);
+			CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(session1.sentStanzas.size()));
+			CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(session2.sentStanzas.size()));
+		}
+
+		void testRouteStanza_FullJIDWithNegativePriority() {
+			ServerStanzaRouter testling;
+			MockServerSession session1(JID("foo@bar.com/Bla"), -1);
+			testling.addClientSession(&session1);
+			MockServerSession session2(JID("foo@bar.com/Baz"), 0);
+			testling.addClientSession(&session2);
+
+			bool result = testling.routeStanza(createMessageTo("foo@bar.com/Bla"));
+
+			CPPUNIT_ASSERT(result);
+			CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(session1.sentStanzas.size()));
+			CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(session2.sentStanzas.size()));
+		}
+
+		void testRouteStanza_FullJIDWithOnlyBareJIDMatchingSession() {
+			ServerStanzaRouter testling;
+			MockServerSession session(JID("foo@bar.com/Bla"), 0);
+			testling.addClientSession(&session);
+
+			bool result = testling.routeStanza(createMessageTo("foo@bar.com/Baz"));
+
+			CPPUNIT_ASSERT(result);
+			CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(session.sentStanzas.size()));
+		}
+
+		void testRouteStanza_BareJIDWithoutMatchingSession() {
+			ServerStanzaRouter testling;
+
+			bool result = testling.routeStanza(createMessageTo("foo@bar.com"));
+
+			CPPUNIT_ASSERT(!result);
+		}
+
+		void testRouteStanza_BareJIDWithMultipleSessions() {
+			ServerStanzaRouter testling;
+			MockServerSession session1(JID("foo@bar.com/Bla"), 1);
+			testling.addClientSession(&session1);
+			MockServerSession session2(JID("foo@bar.com/Baz"), 8);
+			testling.addClientSession(&session2);
+			MockServerSession session3(JID("foo@bar.com/Bar"), 5);
+			testling.addClientSession(&session3);
+
+			bool result = testling.routeStanza(createMessageTo("foo@bar.com"));
+
+			CPPUNIT_ASSERT(result);
+			CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(session1.sentStanzas.size()));
+			CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(session2.sentStanzas.size()));
+			CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(session3.sentStanzas.size()));
+		}
+
+		void testRouteStanza_BareJIDWithOnlyNegativePriorities() {
+			ServerStanzaRouter testling;
+			MockServerSession session(JID("foo@bar.com/Bla"), -1);
+			testling.addClientSession(&session);
+
+			bool result = testling.routeStanza(createMessageTo("foo@bar.com"));
+
+			CPPUNIT_ASSERT(!result);
+		}
+
+		void testRouteStanza_BareJIDWithChangingPresence() {
+			ServerStanzaRouter testling;
+			MockServerSession session1(JID("foo@bar.com/Baz"), 8);
+			testling.addClientSession(&session1);
+			MockServerSession session2(JID("foo@bar.com/Bar"), 5);
+			testling.addClientSession(&session2);
+
+			session1.priority = 3;
+			session2.priority = 4;
+			bool result = testling.routeStanza(createMessageTo("foo@bar.com"));
+
+			CPPUNIT_ASSERT(result);
+			CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(session1.sentStanzas.size()));
+			CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(session2.sentStanzas.size()));
+		}
+
+	private:
+		boost::shared_ptr<Message> createMessageTo(const std::string& recipient) {
+			boost::shared_ptr<Message> message(new Message());
+			message->setTo(JID(recipient));
+			return message;
+		}
+
+		class MockServerSession : public ServerSession {
+			public:
+				MockServerSession(const JID& jid, int priority) : jid(jid), priority(priority) {}
+
+				virtual const JID& getJID() const { return jid; }
+				virtual int getPriority() const { return priority; }
+
+				virtual void sendStanza(boost::shared_ptr<Stanza> stanza) {
+					sentStanzas.push_back(stanza);
+				}
+
+				JID jid;
+				int priority;
+				std::vector< boost::shared_ptr<Stanza> > sentStanzas;
+		};
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(ServerStanzaRouterTest);
diff --git a/Limber/Server/UserRegistry.cpp b/Limber/Server/UserRegistry.cpp
new file mode 100644
index 0000000..5ac462a
--- /dev/null
+++ b/Limber/Server/UserRegistry.cpp
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include "Limber/Server/UserRegistry.h"
+
+namespace Swift {
+
+UserRegistry::~UserRegistry() {
+}
+
+}
diff --git a/Limber/Server/UserRegistry.h b/Limber/Server/UserRegistry.h
new file mode 100644
index 0000000..c021fc4
--- /dev/null
+++ b/Limber/Server/UserRegistry.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <string>
+
+namespace Swift {
+	
+	class JID;
+
+	class UserRegistry {
+		public:
+			virtual ~UserRegistry();
+
+			virtual bool isValidUserPassword(const JID& user, const std::string& password) const = 0;
+	};
+}
diff --git a/Limber/main.cpp b/Limber/main.cpp
index 6db623e..e6bc45d 100644
--- a/Limber/main.cpp
+++ b/Limber/main.cpp
@@ -11,7 +11,6 @@
 #include "Swiften/Elements/IQ.h"
 #include "Swiften/Elements/RosterPayload.h"
 #include "Swiften/Elements/VCard.h"
-#include "Swiften/Server/SimpleUserRegistry.h"
 #include "Swiften/Base/IDGenerator.h"
 #include "Swiften/EventLoop/EventLoop.h"
 #include "Swiften/EventLoop/SimpleEventLoop.h"
@@ -21,7 +20,8 @@
 #include "Swiften/Network/BoostConnection.h"
 #include "Swiften/Network/BoostIOServiceThread.h"
 #include "Swiften/Network/BoostConnectionServer.h"
-#include "Swiften/Server/ServerFromClientSession.h"
+#include "Limber/Server/SimpleUserRegistry.h"
+#include "Limber/Server/ServerFromClientSession.h"
 #include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h"
 #include "Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h"
 
diff --git a/QA/UnitTest/SConscript b/QA/UnitTest/SConscript
index 25e9b05..76abbcb 100644
--- a/QA/UnitTest/SConscript
+++ b/QA/UnitTest/SConscript
@@ -12,6 +12,7 @@ if env["TEST"] :
 		myenv.MergeFlags(env.get("SLIMBER_FLAGS",""))
 		myenv.MergeFlags(env.get("SWIFT_CONTROLLERS_FLAGS",""))
 		myenv.MergeFlags(env.get("SWIFTOOLS_FLAGS",""))
+		myenv.MergeFlags(env.get("LIMBER_FLAGS",""))
 		myenv.MergeFlags(env.get("SWIFTEN_FLAGS",""))
 		myenv.MergeFlags(env.get("CPPUNIT_FLAGS",""))
 		myenv.MergeFlags(env.get("LIBIDN_FLAGS", ""))
diff --git a/Slimber/CLI/SConscript b/Slimber/CLI/SConscript
index fddd717..422b56c 100644
--- a/Slimber/CLI/SConscript
+++ b/Slimber/CLI/SConscript
@@ -1,6 +1,7 @@
 Import("env")
 
 myenv = env.Clone()
+myenv.UseFlags(env["LIMBER_FLAGS"])
 myenv.MergeFlags(env["SLIMBER_FLAGS"])
 myenv.MergeFlags(env["SWIFTOOLS_FLAGS"])
 myenv.MergeFlags(env["SWIFTEN_FLAGS"])
diff --git a/Slimber/Cocoa/SConscript b/Slimber/Cocoa/SConscript
index e2d8221..e122d87 100644
--- a/Slimber/Cocoa/SConscript
+++ b/Slimber/Cocoa/SConscript
@@ -1,6 +1,7 @@
 Import("env")
 
 myenv = env.Clone()
+myenv.UseFlags(env["LIMBER_FLAGS"])
 myenv.MergeFlags(env["SLIMBER_FLAGS"])
 myenv.MergeFlags(env["SWIFTOOLS_FLAGS"])
 myenv.MergeFlags(env["SWIFTEN_FLAGS"])
diff --git a/Slimber/SConscript b/Slimber/SConscript
index 9a84c17..11beee6 100644
--- a/Slimber/SConscript
+++ b/Slimber/SConscript
@@ -31,6 +31,7 @@ if "Slimber" in env["PROJECTS"] :
 
 	if env["SCONS_STAGE"] == "build" :
 		myenv = env.Clone()
+		myenv.UseFlags(env["LIMBER_FLAGS"])
 		myenv.MergeFlags(env["BOOST_FLAGS"])
 		myenv.MergeFlags(env["SWIFTEN_FLAGS"])
 		myenv.StaticLibrary("Slimber", [
diff --git a/Slimber/Server.cpp b/Slimber/Server.cpp
index 380ce6a..d1d0e24 100644
--- a/Slimber/Server.cpp
+++ b/Slimber/Server.cpp
@@ -21,7 +21,7 @@
 #include "Swiften/Session/SessionTracer.h"
 #include "Swiften/Elements/IQ.h"
 #include "Swiften/Elements/VCard.h"
-#include "Swiften/Server/UserRegistry.h"
+#include "Limber/Server/UserRegistry.h"
 #include <string>
 #include "Swiften/LinkLocal/LinkLocalServiceInfo.h"
 #include "Swiften/LinkLocal/OutgoingLinkLocalSession.h"
@@ -30,7 +30,7 @@
 #include "Swiften/Network/ConnectionServer.h"
 #include "Slimber/VCardCollection.h"
 #include "Slimber/LinkLocalPresenceManager.h"
-#include "Swiften/Server/ServerFromClientSession.h"
+#include "Limber/Server/ServerFromClientSession.h"
 
 namespace Swift {
 
diff --git a/Slimber/Server.h b/Slimber/Server.h
index 98332fd..d1a2332 100644
--- a/Slimber/Server.h
+++ b/Slimber/Server.h
@@ -12,9 +12,9 @@
 
 #include "Swiften/Network/BoostIOServiceThread.h"
 #include "Swiften/Network/BoostConnectionServer.h"
-#include "Swiften/Server/UserRegistry.h"
+#include "Limber/Server/UserRegistry.h"
 #include "Swiften/Base/IDGenerator.h"
-#include "Swiften/Server/ServerFromClientSession.h"
+#include "Limber/Server/ServerFromClientSession.h"
 #include "Swiften/JID/JID.h"
 #include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h"
 #include "Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h"
diff --git a/Swiften/SConscript b/Swiften/SConscript
index 110f202..30fd9b6 100644
--- a/Swiften/SConscript
+++ b/Swiften/SConscript
@@ -153,11 +153,6 @@ if env["SCONS_STAGE"] == "build" :
 			"Serializer/XML/XMLElement.cpp",
 			"Serializer/XML/XMLNode.cpp",
 			"Serializer/XMPPSerializer.cpp",
-			"Server/ServerFromClientSession.cpp",
-			"Server/ServerSession.cpp",
-			"Server/ServerStanzaRouter.cpp",
-			"Server/SimpleUserRegistry.cpp",
-			"Server/UserRegistry.cpp",
 			"Session/Session.cpp",
 			"Session/SessionStream.cpp",
 			"Session/BasicSessionStream.cpp",
diff --git a/Swiften/Server/ServerFromClientSession.cpp b/Swiften/Server/ServerFromClientSession.cpp
deleted file mode 100644
index 18da7e8..0000000
--- a/Swiften/Server/ServerFromClientSession.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#include "Swiften/Server/ServerFromClientSession.h"
-
-#include <boost/bind.hpp>
-
-#include "Swiften/Elements/ProtocolHeader.h"
-#include "Swiften/Server/UserRegistry.h"
-#include "Swiften/Network/Connection.h"
-#include "Swiften/StreamStack/XMPPLayer.h"
-#include "Swiften/Elements/StreamFeatures.h"
-#include "Swiften/Elements/ResourceBind.h"
-#include "Swiften/Elements/StartSession.h"
-#include "Swiften/Elements/IQ.h"
-#include "Swiften/Elements/AuthSuccess.h"
-#include "Swiften/Elements/AuthFailure.h"
-#include "Swiften/Elements/AuthRequest.h"
-#include "Swiften/SASL/PLAINMessage.h"
-
-namespace Swift {
-
-ServerFromClientSession::ServerFromClientSession(
-		const std::string& id,
-		boost::shared_ptr<Connection> connection, 
-		PayloadParserFactoryCollection* payloadParserFactories, 
-		PayloadSerializerCollection* payloadSerializers,
-		UserRegistry* userRegistry) : 
-			Session(connection, payloadParserFactories, payloadSerializers),
-			id_(id),
-			userRegistry_(userRegistry),
-			authenticated_(false),
-			initialized(false),
-			allowSASLEXTERNAL(false) {
-}
-
-
-void ServerFromClientSession::handleElement(boost::shared_ptr<Element> element) {
-	if (isInitialized()) {
-		onElementReceived(element);
-	}
-	else {
-		if (AuthRequest* authRequest = dynamic_cast<AuthRequest*>(element.get())) {
-			if (authRequest->getMechanism() == "PLAIN" || (allowSASLEXTERNAL && authRequest->getMechanism() == "EXTERNAL")) {
-				if (authRequest->getMechanism() == "EXTERNAL") {
-						getXMPPLayer()->writeElement(boost::shared_ptr<AuthSuccess>(new AuthSuccess()));
-						authenticated_ = true;
-						getXMPPLayer()->resetParser();
-				}
-				else {
-					PLAINMessage plainMessage(authRequest->getMessage() ? *authRequest->getMessage() : "");
-					if (userRegistry_->isValidUserPassword(JID(plainMessage.getAuthenticationID(), getLocalJID().getDomain()), plainMessage.getPassword())) {
-						getXMPPLayer()->writeElement(boost::shared_ptr<AuthSuccess>(new AuthSuccess()));
-						user_ = plainMessage.getAuthenticationID();
-						authenticated_ = true;
-						getXMPPLayer()->resetParser();
-					}
-					else {
-						getXMPPLayer()->writeElement(boost::shared_ptr<AuthFailure>(new AuthFailure));
-						finishSession(AuthenticationFailedError);
-					}
-				}
-			}
-			else {
-				getXMPPLayer()->writeElement(boost::shared_ptr<AuthFailure>(new AuthFailure));
-				finishSession(NoSupportedAuthMechanismsError);
-			}
-		}
-		else if (IQ* iq = dynamic_cast<IQ*>(element.get())) {
-			if (boost::shared_ptr<ResourceBind> resourceBind = iq->getPayload<ResourceBind>()) {
-				setRemoteJID(JID(user_, getLocalJID().getDomain(), resourceBind->getResource()));
-				boost::shared_ptr<ResourceBind> resultResourceBind(new ResourceBind());
-				resultResourceBind->setJID(getRemoteJID());
-				getXMPPLayer()->writeElement(IQ::createResult(JID(), iq->getID(), resultResourceBind));
-			}
-			else if (iq->getPayload<StartSession>()) {
-				getXMPPLayer()->writeElement(IQ::createResult(getRemoteJID(), iq->getID()));
-				setInitialized();
-			}
-		}
-	}
-}
-
-void ServerFromClientSession::handleStreamStart(const ProtocolHeader& incomingHeader) {
-	setLocalJID(JID("", incomingHeader.getTo()));
-	ProtocolHeader header;
-	header.setFrom(incomingHeader.getTo());
-	header.setID(id_);
-	getXMPPLayer()->writeHeader(header);
-
-	boost::shared_ptr<StreamFeatures> features(new StreamFeatures());
-	if (!authenticated_) {
-		features->addAuthenticationMechanism("PLAIN");
-		if (allowSASLEXTERNAL) {
-			features->addAuthenticationMechanism("EXTERNAL");
-		}
-	}
-	else {
-		features->setHasResourceBind();
-		features->setHasSession();
-	}
-	getXMPPLayer()->writeElement(features);
-}
-
-void ServerFromClientSession::setInitialized() {
-	initialized = true;
-	onSessionStarted();
-}
-
-void ServerFromClientSession::setAllowSASLEXTERNAL() {
-	allowSASLEXTERNAL = true;
-}
-
-}
diff --git a/Swiften/Server/ServerFromClientSession.h b/Swiften/Server/ServerFromClientSession.h
deleted file mode 100644
index 80ef063..0000000
--- a/Swiften/Server/ServerFromClientSession.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#pragma once
-
-#include <boost/shared_ptr.hpp>
-#include "Swiften/Base/boost_bsignals.h"
-#include <boost/enable_shared_from_this.hpp>
-
-#include <string>
-#include "Swiften/Session/Session.h"
-#include "Swiften/JID/JID.h"
-#include "Swiften/Network/Connection.h"
-
-namespace Swift {
-	class ProtocolHeader;
-	class Element;
-	class Stanza;
-	class PayloadParserFactoryCollection;
-	class PayloadSerializerCollection;
-	class StreamStack;
-	class UserRegistry;
-	class XMPPLayer;
-	class ConnectionLayer;
-	class Connection;
-	class ByteArray;
-
-	class ServerFromClientSession : public Session {
-		public:
-			ServerFromClientSession(
-					const std::string& id,
-					boost::shared_ptr<Connection> connection, 
-					PayloadParserFactoryCollection* payloadParserFactories, 
-					PayloadSerializerCollection* payloadSerializers,
-					UserRegistry* userRegistry);
-
-			boost::signal<void ()> onSessionStarted;
-			void setAllowSASLEXTERNAL();
-
-		private:
-			void handleElement(boost::shared_ptr<Element>);
-			void handleStreamStart(const ProtocolHeader& header);
-
-			void setInitialized();
-			bool isInitialized() const { 
-				return initialized; 
-			}
-
-		private:
-			std::string id_;
-			UserRegistry* userRegistry_;
-			bool authenticated_;
-			bool initialized;
-			bool allowSASLEXTERNAL;
-			std::string user_;
-	};
-}
diff --git a/Swiften/Server/ServerSession.cpp b/Swiften/Server/ServerSession.cpp
deleted file mode 100644
index 10d642d..0000000
--- a/Swiften/Server/ServerSession.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#include "Swiften/Server/ServerSession.h"
-
-namespace Swift {
-
-ServerSession::~ServerSession() {
-}
-
-}
diff --git a/Swiften/Server/ServerSession.h b/Swiften/Server/ServerSession.h
deleted file mode 100644
index bd4ab6d..0000000
--- a/Swiften/Server/ServerSession.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#pragma once
-
-#include <boost/shared_ptr.hpp>
-
-#include "Swiften/Elements/Stanza.h"
-
-namespace Swift {
-	class ServerSession {
-		public:
-			virtual ~ServerSession();
-
-			virtual const JID& getJID() const = 0;
-			virtual int getPriority() const = 0;
-
-			virtual void sendStanza(boost::shared_ptr<Stanza>) = 0;
-	};
-}
diff --git a/Swiften/Server/ServerStanzaRouter.cpp b/Swiften/Server/ServerStanzaRouter.cpp
deleted file mode 100644
index b4d230a..0000000
--- a/Swiften/Server/ServerStanzaRouter.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#include "Swiften/Server/ServerStanzaRouter.h"
-#include "Swiften/Server/ServerSession.h"
-
-#include <cassert>
-#include <algorithm>
-
-namespace Swift {
-
-namespace {
-	struct PriorityLessThan {
-		bool operator()(const ServerSession* s1, const ServerSession* s2) const {
-			return s1->getPriority() < s2->getPriority();
-		}
-	};
-
-	struct HasJID {
-		HasJID(const JID& jid) : jid(jid) {}
-		bool operator()(const ServerSession* session) const {
-			return session->getJID().equals(jid, JID::WithResource);
-		}
-		JID jid;
-	};
-}
-
-ServerStanzaRouter::ServerStanzaRouter() {
-}
-
-bool ServerStanzaRouter::routeStanza(boost::shared_ptr<Stanza> stanza) {
-	JID to = stanza->getTo();
-	assert(to.isValid());
-
-	// For a full JID, first try to route to a session with the full JID
-	if (!to.isBare()) {
-		std::vector<ServerSession*>::const_iterator i = std::find_if(clientSessions_.begin(), clientSessions_.end(), HasJID(to));
-		if (i != clientSessions_.end()) {
-			(*i)->sendStanza(stanza);
-			return true;
-		}
-	}
-
-	// Look for candidate sessions
-	to = to.toBare();
-	std::vector<ServerSession*> candidateSessions;
-	for (std::vector<ServerSession*>::const_iterator i = clientSessions_.begin(); i != clientSessions_.end(); ++i) {
-		if ((*i)->getJID().equals(to, JID::WithoutResource) && (*i)->getPriority() >= 0) {
-			candidateSessions.push_back(*i);
-		}
-	}
-	if (candidateSessions.empty()) {
-		return false;
-	}
-
-	// Find the session with the highest priority
-	std::vector<ServerSession*>::const_iterator i = std::max_element(clientSessions_.begin(), clientSessions_.end(), PriorityLessThan());
-	(*i)->sendStanza(stanza);
-	return true;
-}
-
-void ServerStanzaRouter::addClientSession(ServerSession* clientSession) {
-	clientSessions_.push_back(clientSession);
-}
-
-void ServerStanzaRouter::removeClientSession(ServerSession* clientSession) {
-	clientSessions_.erase(std::remove(clientSessions_.begin(), clientSessions_.end(), clientSession), clientSessions_.end());
-}
-
-}
diff --git a/Swiften/Server/ServerStanzaRouter.h b/Swiften/Server/ServerStanzaRouter.h
deleted file mode 100644
index 2a1960c..0000000
--- a/Swiften/Server/ServerStanzaRouter.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#pragma once
-
-#include <boost/shared_ptr.hpp>
-#include <map>
-
-#include "Swiften/JID/JID.h"
-#include "Swiften/Elements/Stanza.h"
-
-namespace Swift {
-	class ServerSession;
-
-	class ServerStanzaRouter {
-		public:
-			ServerStanzaRouter();
-
-			bool routeStanza(boost::shared_ptr<Stanza>);
-
-			void addClientSession(ServerSession*);
-			void removeClientSession(ServerSession*);
-
-		private:
-			std::vector<ServerSession*> clientSessions_;
-	};
-}
diff --git a/Swiften/Server/SimpleUserRegistry.cpp b/Swiften/Server/SimpleUserRegistry.cpp
deleted file mode 100644
index 2de28fe..0000000
--- a/Swiften/Server/SimpleUserRegistry.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#include "Swiften/Server/SimpleUserRegistry.h"
-
-namespace Swift {
-
-SimpleUserRegistry::SimpleUserRegistry() {
-}
-
-bool SimpleUserRegistry::isValidUserPassword(const JID& user, const std::string& password) const {
-	std::map<JID,std::string>::const_iterator i = users.find(user);
-	return i != users.end() ? i->second == password : false;
-}
-
-void SimpleUserRegistry::addUser(const JID& user, const std::string& password) {
-	users.insert(std::make_pair(user, password));
-}
-
-}
diff --git a/Swiften/Server/SimpleUserRegistry.h b/Swiften/Server/SimpleUserRegistry.h
deleted file mode 100644
index 5de9f64..0000000
--- a/Swiften/Server/SimpleUserRegistry.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#pragma once
-
-#include <map>
-
-#include "Swiften/JID/JID.h"
-#include <string>
-#include "Swiften/Server/UserRegistry.h"
-
-namespace Swift {
-	
-
-	class SimpleUserRegistry : public UserRegistry {
-		public:
-			SimpleUserRegistry();
-
-			virtual bool isValidUserPassword(const JID& user, const std::string& password) const;
-			void addUser(const JID& user, const std::string& password);
-
-		private:
-			std::map<JID, std::string> users;
-	};
-}
diff --git a/Swiften/Server/UnitTest/ServerStanzaRouterTest.cpp b/Swiften/Server/UnitTest/ServerStanzaRouterTest.cpp
deleted file mode 100644
index 0a5c7c1..0000000
--- a/Swiften/Server/UnitTest/ServerStanzaRouterTest.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#include <cppunit/extensions/HelperMacros.h>
-#include <cppunit/extensions/TestFactoryRegistry.h>
-
-#include "Swiften/Elements/Message.h"
-#include "Swiften/Server/ServerStanzaRouter.h"
-#include "Swiften/Server/ServerSession.h"
-
-using namespace Swift;
-
-class ServerStanzaRouterTest : public CppUnit::TestFixture {
-		CPPUNIT_TEST_SUITE(ServerStanzaRouterTest);
-		CPPUNIT_TEST(testRouteStanza_FullJID);
-		CPPUNIT_TEST(testRouteStanza_FullJIDWithNegativePriority);
-		CPPUNIT_TEST(testRouteStanza_FullJIDWithOnlyBareJIDMatchingSession);
-		CPPUNIT_TEST(testRouteStanza_BareJIDWithoutMatchingSession);
-		CPPUNIT_TEST(testRouteStanza_BareJIDWithMultipleSessions);
-		CPPUNIT_TEST(testRouteStanza_BareJIDWithOnlyNegativePriorities);
-		CPPUNIT_TEST(testRouteStanza_BareJIDWithChangingPresence);
-		CPPUNIT_TEST_SUITE_END();
-
-	public:
-		ServerStanzaRouterTest() {}
-
-		void setUp() {
-		}
-
-		void tearDown() {
-		}
-
-		void testRouteStanza_FullJID() {
-			ServerStanzaRouter testling;
-			MockServerSession session1(JID("foo@bar.com/Bla"), 0);
-			testling.addClientSession(&session1);
-			MockServerSession session2(JID("foo@bar.com/Baz"), 0);
-			testling.addClientSession(&session2);
-
-			bool result = testling.routeStanza(createMessageTo("foo@bar.com/Baz"));
-
-			CPPUNIT_ASSERT(result);
-			CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(session1.sentStanzas.size()));
-			CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(session2.sentStanzas.size()));
-		}
-
-		void testRouteStanza_FullJIDWithNegativePriority() {
-			ServerStanzaRouter testling;
-			MockServerSession session1(JID("foo@bar.com/Bla"), -1);
-			testling.addClientSession(&session1);
-			MockServerSession session2(JID("foo@bar.com/Baz"), 0);
-			testling.addClientSession(&session2);
-
-			bool result = testling.routeStanza(createMessageTo("foo@bar.com/Bla"));
-
-			CPPUNIT_ASSERT(result);
-			CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(session1.sentStanzas.size()));
-			CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(session2.sentStanzas.size()));
-		}
-
-		void testRouteStanza_FullJIDWithOnlyBareJIDMatchingSession() {
-			ServerStanzaRouter testling;
-			MockServerSession session(JID("foo@bar.com/Bla"), 0);
-			testling.addClientSession(&session);
-
-			bool result = testling.routeStanza(createMessageTo("foo@bar.com/Baz"));
-
-			CPPUNIT_ASSERT(result);
-			CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(session.sentStanzas.size()));
-		}
-
-		void testRouteStanza_BareJIDWithoutMatchingSession() {
-			ServerStanzaRouter testling;
-
-			bool result = testling.routeStanza(createMessageTo("foo@bar.com"));
-
-			CPPUNIT_ASSERT(!result);
-		}
-
-		void testRouteStanza_BareJIDWithMultipleSessions() {
-			ServerStanzaRouter testling;
-			MockServerSession session1(JID("foo@bar.com/Bla"), 1);
-			testling.addClientSession(&session1);
-			MockServerSession session2(JID("foo@bar.com/Baz"), 8);
-			testling.addClientSession(&session2);
-			MockServerSession session3(JID("foo@bar.com/Bar"), 5);
-			testling.addClientSession(&session3);
-
-			bool result = testling.routeStanza(createMessageTo("foo@bar.com"));
-
-			CPPUNIT_ASSERT(result);
-			CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(session1.sentStanzas.size()));
-			CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(session2.sentStanzas.size()));
-			CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(session3.sentStanzas.size()));
-		}
-
-		void testRouteStanza_BareJIDWithOnlyNegativePriorities() {
-			ServerStanzaRouter testling;
-			MockServerSession session(JID("foo@bar.com/Bla"), -1);
-			testling.addClientSession(&session);
-
-			bool result = testling.routeStanza(createMessageTo("foo@bar.com"));
-
-			CPPUNIT_ASSERT(!result);
-		}
-
-		void testRouteStanza_BareJIDWithChangingPresence() {
-			ServerStanzaRouter testling;
-			MockServerSession session1(JID("foo@bar.com/Baz"), 8);
-			testling.addClientSession(&session1);
-			MockServerSession session2(JID("foo@bar.com/Bar"), 5);
-			testling.addClientSession(&session2);
-
-			session1.priority = 3;
-			session2.priority = 4;
-			bool result = testling.routeStanza(createMessageTo("foo@bar.com"));
-
-			CPPUNIT_ASSERT(result);
-			CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(session1.sentStanzas.size()));
-			CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(session2.sentStanzas.size()));
-		}
-
-	private:
-		boost::shared_ptr<Message> createMessageTo(const std::string& recipient) {
-			boost::shared_ptr<Message> message(new Message());
-			message->setTo(JID(recipient));
-			return message;
-		}
-
-		class MockServerSession : public ServerSession {
-			public:
-				MockServerSession(const JID& jid, int priority) : jid(jid), priority(priority) {}
-
-				virtual const JID& getJID() const { return jid; }
-				virtual int getPriority() const { return priority; }
-
-				virtual void sendStanza(boost::shared_ptr<Stanza> stanza) {
-					sentStanzas.push_back(stanza);
-				}
-
-				JID jid;
-				int priority;
-				std::vector< boost::shared_ptr<Stanza> > sentStanzas;
-		};
-};
-
-CPPUNIT_TEST_SUITE_REGISTRATION(ServerStanzaRouterTest);
diff --git a/Swiften/Server/UserRegistry.cpp b/Swiften/Server/UserRegistry.cpp
deleted file mode 100644
index 0795f16..0000000
--- a/Swiften/Server/UserRegistry.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#include "Swiften/Server/UserRegistry.h"
-
-namespace Swift {
-
-UserRegistry::~UserRegistry() {
-}
-
-}
diff --git a/Swiften/Server/UserRegistry.h b/Swiften/Server/UserRegistry.h
deleted file mode 100644
index c021fc4..0000000
--- a/Swiften/Server/UserRegistry.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#pragma once
-
-#include <string>
-
-namespace Swift {
-	
-	class JID;
-
-	class UserRegistry {
-		public:
-			virtual ~UserRegistry();
-
-			virtual bool isValidUserPassword(const JID& user, const std::string& password) const = 0;
-	};
-}
-- 
cgit v0.10.2-6-g49f6