From d80935c165ac2709b1dfba1f38c06f2cc1d91ee9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Mon, 25 Apr 2011 09:26:20 +0200
Subject: Moved file storages to Swift.


diff --git a/Swift/Controllers/CertificateFileStorage.cpp b/Swift/Controllers/CertificateFileStorage.cpp
deleted file mode 100644
index cf924ee..0000000
--- a/Swift/Controllers/CertificateFileStorage.cpp
+++ /dev/null
@@ -1,61 +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 <Swift/Controllers/CertificateFileStorage.h>
-
-#include <iostream>
-#include <boost/filesystem/fstream.hpp>
-
-#include <Swiften/StringCodecs/SHA1.h>
-#include <Swiften/StringCodecs/Hexify.h>
-#include <Swiften/TLS/CertificateFactory.h>
-#include <Swiften/Base/Log.h>
-
-namespace Swift {
-
-CertificateFileStorage::CertificateFileStorage(const boost::filesystem::path& path, CertificateFactory* certificateFactory) : path(path), certificateFactory(certificateFactory) {
-}
-
-bool CertificateFileStorage::hasCertificate(Certificate::ref certificate) const {
-	boost::filesystem::path certificatePath = getCertificatePath(certificate);
-	if (boost::filesystem::exists(certificatePath)) {
-		ByteArray data;
-		data.readFromFile(certificatePath.string());
-		Certificate::ref storedCertificate = certificateFactory->createCertificateFromDER(data);
-		if (storedCertificate && storedCertificate->toDER() == certificate->toDER()) {
-			return true;
-		}
-		else {
-			SWIFT_LOG(warning) << "Stored certificate does not match received certificate" << std::endl;
-			return false;
-		}
-	}
-	else {
-		return false;
-	}
-}
-
-void CertificateFileStorage::addCertificate(Certificate::ref certificate) {
-	boost::filesystem::path certificatePath = getCertificatePath(certificate);
-	if (!boost::filesystem::exists(certificatePath.parent_path())) {
-		try {
-			boost::filesystem::create_directories(certificatePath.parent_path());
-		}
-		catch (const boost::filesystem::filesystem_error& e) {
-			std::cerr << "ERROR: " << e.what() << std::endl;
-		}
-	}
-	boost::filesystem::ofstream file(certificatePath, boost::filesystem::ofstream::binary|boost::filesystem::ofstream::out);
-	ByteArray data = certificate->toDER();
-	file.write(reinterpret_cast<const char*>(data.getData()), data.getSize());
-	file.close();
-}
-
-boost::filesystem::path CertificateFileStorage::getCertificatePath(Certificate::ref certificate) const {
-	return path / Hexify::hexify(SHA1::getHash(certificate->toDER()));
-}
-
-}
diff --git a/Swift/Controllers/CertificateFileStorage.h b/Swift/Controllers/CertificateFileStorage.h
deleted file mode 100644
index 2b853ed..0000000
--- a/Swift/Controllers/CertificateFileStorage.h
+++ /dev/null
@@ -1,31 +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/filesystem.hpp>
-
-#include "Swift/Controllers/CertificateStorage.h"
-
-namespace Swift {
-	class CertificateFactory;
-
-	class CertificateFileStorage : public CertificateStorage {
-		public:
-			CertificateFileStorage(const boost::filesystem::path& path, CertificateFactory* certificateFactory);
-
-			virtual bool hasCertificate(Certificate::ref certificate) const;
-			virtual void addCertificate(Certificate::ref certificate);
-
-		private:
-			boost::filesystem::path getCertificatePath(Certificate::ref certificate) const;
-
-		private:
-			boost::filesystem::path path;
-			CertificateFactory* certificateFactory;
-	};
-
-}
diff --git a/Swift/Controllers/CertificateFileStorageFactory.h b/Swift/Controllers/CertificateFileStorageFactory.h
deleted file mode 100644
index 7ed8287..0000000
--- a/Swift/Controllers/CertificateFileStorageFactory.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 <Swift/Controllers/CertificateStorageFactory.h>
-#include <Swift/Controllers/CertificateFileStorage.h>
-
-namespace Swift {
-	class CertificateFactory;
-
-	class CertificateFileStorageFactory : public CertificateStorageFactory {
-		public:
-			CertificateFileStorageFactory(const boost::filesystem::path& basePath, CertificateFactory* certificateFactory) : basePath(basePath), certificateFactory(certificateFactory) {}
-
-			virtual CertificateStorage* createCertificateStorage(const JID& profile) const {
-				boost::filesystem::path profilePath = basePath / profile.toString();
-				return new CertificateFileStorage(profilePath / "certificates", certificateFactory);
-			}
-
-		private:
-			boost::filesystem::path basePath;
-			CertificateFactory* certificateFactory;
-	};
-}
diff --git a/Swift/Controllers/CertificateStorage.cpp b/Swift/Controllers/CertificateStorage.cpp
deleted file mode 100644
index 343fccd..0000000
--- a/Swift/Controllers/CertificateStorage.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 "Swift/Controllers/CertificateStorage.h"
-
-namespace Swift {
-
-CertificateStorage::~CertificateStorage() {
-}
-
-}
diff --git a/Swift/Controllers/CertificateStorage.h b/Swift/Controllers/CertificateStorage.h
deleted file mode 100644
index f8c6fb5..0000000
--- a/Swift/Controllers/CertificateStorage.h
+++ /dev/null
@@ -1,22 +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/filesystem.hpp>
-
-#include <Swiften/TLS/Certificate.h>
-
-namespace Swift {
-	class CertificateStorage {
-		public:
-			virtual ~CertificateStorage();
-
-			virtual bool hasCertificate(Certificate::ref certificate) const = 0;
-			virtual void addCertificate(Certificate::ref certificate) = 0;
-	};
-
-}
diff --git a/Swift/Controllers/CertificateStorageFactory.cpp b/Swift/Controllers/CertificateStorageFactory.cpp
deleted file mode 100644
index 613a8c3..0000000
--- a/Swift/Controllers/CertificateStorageFactory.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 <Swift/Controllers/CertificateStorageFactory.h>
-
-namespace Swift {
-
-CertificateStorageFactory::~CertificateStorageFactory() {
-}
-
-}
diff --git a/Swift/Controllers/CertificateStorageFactory.h b/Swift/Controllers/CertificateStorageFactory.h
deleted file mode 100644
index 5b85757..0000000
--- a/Swift/Controllers/CertificateStorageFactory.h
+++ /dev/null
@@ -1,19 +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
-
-namespace Swift {
-	class CertificateStorage;
-	class JID;
-
-	class CertificateStorageFactory {
-		public:
-			virtual ~CertificateStorageFactory();
-
-			virtual CertificateStorage* createCertificateStorage(const JID& profile) const = 0;
-	};
-}
diff --git a/Swift/Controllers/CertificateStorageTrustChecker.h b/Swift/Controllers/CertificateStorageTrustChecker.h
deleted file mode 100644
index f33287c..0000000
--- a/Swift/Controllers/CertificateStorageTrustChecker.h
+++ /dev/null
@@ -1,34 +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 <Swiften/TLS/CertificateTrustChecker.h>
-#include <Swift/Controllers/CertificateStorage.h>
-
-namespace Swift {
-	/**
-	 * A certificate trust checker that trusts certificates in a certificate storage.
-	 */
-	class CertificateStorageTrustChecker : public CertificateTrustChecker {
-		public:
-			CertificateStorageTrustChecker(CertificateStorage* storage) : storage(storage) {
-			}
-
-			virtual bool isCertificateTrusted(Certificate::ref certificate) {
-				lastCertificate = certificate;
-				return storage->hasCertificate(certificate);
-			}
-
-			Certificate::ref getLastCertificate() const {
-				return lastCertificate;
-			}
-
-		private:
-			CertificateStorage* storage;
-			Certificate::ref lastCertificate;
-	};
-}
diff --git a/Swift/Controllers/FileStoragesFactory.h b/Swift/Controllers/FileStoragesFactory.h
deleted file mode 100644
index bd7cdfb..0000000
--- a/Swift/Controllers/FileStoragesFactory.h
+++ /dev/null
@@ -1,24 +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 "Swift/Controllers/StoragesFactory.h"
-#include "Swiften/Client/FileStorages.h"
-
-namespace Swift {
-	class FileStoragesFactory : public StoragesFactory {
-		public:
-			FileStoragesFactory(const boost::filesystem::path& basePath) : basePath(basePath) {}
-
-			virtual Storages* createStorages(const JID& profile) const {
-				return new FileStorages(basePath, profile);
-			}
-
-		private:
-			boost::filesystem::path basePath;
-	};
-}
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index efe4de4..d94094b 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -18,8 +18,7 @@
 #include <Swift/Controllers/UIInterfaces/UIFactory.h>
 #include "Swiften/Network/TimerFactory.h"
 #include "Swift/Controllers/BuildVersion.h"
-#include "Swift/Controllers/StoragesFactory.h"
-#include "Swiften/Client/Storages.h"
+#include "Swift/Controllers/Storages/StoragesFactory.h"
 #include "Swiften/VCards/VCardManager.h"
 #include "Swift/Controllers/Chat/UserSearchController.h"
 #include "Swift/Controllers/Chat/ChatsManager.h"
@@ -59,8 +58,8 @@
 #include "Swift/Controllers/UIEvents/RequestChatUIEvent.h"
 #include "Swift/Controllers/UIEvents/ToggleNotificationsUIEvent.h"
 #include "Swift/Controllers/UIEvents/JoinMUCUIEvent.h"
-#include "Swift/Controllers/CertificateStorageFactory.h"
-#include "Swift/Controllers/CertificateStorageTrustChecker.h"
+#include "Swift/Controllers/Storages/CertificateStorageFactory.h"
+#include "Swift/Controllers/Storages/CertificateStorageTrustChecker.h"
 #include "Swiften/Network/NetworkFactories.h"
 #include <Swift/Controllers/ProfileController.h>
 #include <Swift/Controllers/ContactEditController.h>
diff --git a/Swift/Controllers/MemoryStoragesFactory.h b/Swift/Controllers/MemoryStoragesFactory.h
deleted file mode 100644
index 8408e10..0000000
--- a/Swift/Controllers/MemoryStoragesFactory.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 "Swift/Controllers/StoragesFactory.h"
-#include "Swiften/Client/MemoryStorages.h"
-
-namespace Swift {
-	class MemoryStoragesFactory : public StoragesFactory {
-		public:
-			MemoryStoragesFactory() {}
-
-			virtual Storages* createStorages(const JID& profile) const {
-				return new MemoryStorages();
-			}
-	};
-}
diff --git a/Swift/Controllers/SConscript b/Swift/Controllers/SConscript
index bd18a3e..5b55892 100644
--- a/Swift/Controllers/SConscript
+++ b/Swift/Controllers/SConscript
@@ -50,9 +50,14 @@ if env["SCONS_STAGE"] == "build" :
 			"UIInterfaces/XMLConsoleWidget.cpp",
 			"UIInterfaces/ChatListWindow.cpp",
 			"PreviousStatusStore.cpp",
-			"CertificateStorageFactory.cpp",
-			"CertificateStorage.cpp",
-			"CertificateFileStorage.cpp",
+			"Storages/CertificateStorageFactory.cpp",
+			"Storages/CertificateStorage.cpp",
+			"Storages/CertificateFileStorage.cpp",
+			"Storages/AvatarFileStorage.cpp",
+			"Storages/FileStorages.cpp",
+			"Storages/RosterFileStorage.cpp",
+			"Storages/CapsFileStorage.cpp",
+			"Storages/VCardFileStorage.cpp",
 			"StatusUtil.cpp",
 			"Translator.cpp",
 			"XMPPURIController.cpp",
diff --git a/Swift/Controllers/Storages/AvatarFileStorage.cpp b/Swift/Controllers/Storages/AvatarFileStorage.cpp
new file mode 100644
index 0000000..288f6fd
--- /dev/null
+++ b/Swift/Controllers/Storages/AvatarFileStorage.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swift/Controllers/Storages/AvatarFileStorage.h>
+
+#include <iostream>
+#include <boost/filesystem/fstream.hpp>
+#include <boost/filesystem.hpp>
+
+#include <Swiften/Base/foreach.h>
+#include <Swiften/Base/String.h>
+#include <Swiften/StringCodecs/SHA1.h>
+#include <Swiften/StringCodecs/Hexify.h>
+
+namespace Swift {
+
+AvatarFileStorage::AvatarFileStorage(const boost::filesystem::path& avatarsDir, const boost::filesystem::path& avatarsFile) : avatarsDir(avatarsDir), avatarsFile(avatarsFile) {
+	if (boost::filesystem::exists(avatarsFile)) {
+		try {
+			boost::filesystem::ifstream file(avatarsFile);
+			std::string line;
+			if (file.is_open()) {
+				while (!file.eof()) {
+					getline(file, line);
+					std::pair<std::string, std::string> r = String::getSplittedAtFirst(line, ' ');
+					JID jid(r.second);
+					if (jid.isValid()) {
+						jidAvatars.insert(std::make_pair(jid, r.first));
+					}
+					else if (!r.first.empty() || !r.second.empty()) {
+						std::cerr << "Invalid entry in avatars file: " << r.second << std::endl;
+					}
+				}
+			}
+		}
+		catch (...) {
+			std::cerr << "Error reading avatars file" << std::endl;
+		}
+	}
+}
+
+bool AvatarFileStorage::hasAvatar(const std::string& hash) const { 
+	return boost::filesystem::exists(getAvatarPath(hash));
+}
+
+void AvatarFileStorage::addAvatar(const std::string& hash, const ByteArray& avatar) {
+	assert(Hexify::hexify(SHA1::getHash(avatar)) == hash);
+
+	boost::filesystem::path avatarPath = getAvatarPath(hash);
+	if (!boost::filesystem::exists(avatarPath.parent_path())) {
+		try {
+			boost::filesystem::create_directories(avatarPath.parent_path());
+		}
+		catch (const boost::filesystem::filesystem_error& e) {
+			std::cerr << "ERROR: " << e.what() << std::endl;
+		}
+	}
+	boost::filesystem::ofstream file(avatarPath, boost::filesystem::ofstream::binary|boost::filesystem::ofstream::out);
+	file.write(reinterpret_cast<const char*>(avatar.getData()), static_cast<std::streamsize>(avatar.getSize()));
+	file.close();
+}
+
+boost::filesystem::path AvatarFileStorage::getAvatarPath(const std::string& hash) const {
+	return avatarsDir / hash;
+}
+
+ByteArray AvatarFileStorage::getAvatar(const std::string& hash) const {
+	ByteArray data;
+	data.readFromFile(getAvatarPath(hash).string());
+	return data;
+}
+
+void AvatarFileStorage::setAvatarForJID(const JID& jid, const std::string& hash) {
+	std::pair<JIDAvatarMap::iterator, bool> r = jidAvatars.insert(std::make_pair(jid, hash));
+	if (r.second) {
+		saveJIDAvatars();
+	}
+	else if (r.first->second != hash) {
+		r.first->second = hash;
+		saveJIDAvatars();
+	}
+}
+
+std::string AvatarFileStorage::getAvatarForJID(const JID& jid) const {
+	JIDAvatarMap::const_iterator i = jidAvatars.find(jid);
+	return i == jidAvatars.end() ? "" : i->second;
+}
+
+void AvatarFileStorage::saveJIDAvatars() {
+	try {
+		boost::filesystem::ofstream file(avatarsFile);
+		for (JIDAvatarMap::const_iterator i = jidAvatars.begin(); i != jidAvatars.end(); ++i) {
+			file << i->second << " " << i->first.toString() << std::endl;
+		}
+		file.close();
+	}
+	catch (...) {
+		std::cerr << "Error writing avatars file" << std::endl;
+	}
+}
+
+}
diff --git a/Swift/Controllers/Storages/AvatarFileStorage.h b/Swift/Controllers/Storages/AvatarFileStorage.h
new file mode 100644
index 0000000..b7e73f5
--- /dev/null
+++ b/Swift/Controllers/Storages/AvatarFileStorage.h
@@ -0,0 +1,41 @@
+/*
+ * 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 <string>
+#include <boost/filesystem/path.hpp>
+
+#include <Swiften/JID/JID.h>
+#include "Swiften/Base/ByteArray.h"
+#include "Swiften/Avatars/AvatarStorage.h"
+
+namespace Swift {
+	class AvatarFileStorage : public AvatarStorage {
+		public:
+			AvatarFileStorage(const boost::filesystem::path& avatarsDir, const boost::filesystem::path& avatarsFile);
+
+			virtual bool hasAvatar(const std::string& hash) const;
+			virtual void addAvatar(const std::string& hash, const ByteArray& avatar);
+			virtual ByteArray getAvatar(const std::string& hash) const;
+
+			virtual boost::filesystem::path getAvatarPath(const std::string& hash) const;
+
+			virtual void setAvatarForJID(const JID& jid, const std::string& hash);
+			virtual std::string getAvatarForJID(const JID& jid) const;
+
+		private:
+			void saveJIDAvatars();
+
+		private:
+			boost::filesystem::path avatarsDir;
+			boost::filesystem::path avatarsFile;
+			typedef std::map<JID, std::string> JIDAvatarMap;
+			JIDAvatarMap jidAvatars;
+	};
+
+}
diff --git a/Swift/Controllers/Storages/CapsFileStorage.cpp b/Swift/Controllers/Storages/CapsFileStorage.cpp
new file mode 100644
index 0000000..b7593fd
--- /dev/null
+++ b/Swift/Controllers/Storages/CapsFileStorage.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include "Swift/Controllers/Storages/CapsFileStorage.h"
+
+#include <Swiften/Entity/GenericPayloadPersister.h>
+#include "Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.h"
+#include "Swiften/Parser/PayloadParsers/DiscoInfoParser.h"
+#include "Swiften/StringCodecs/Hexify.h"
+#include "Swiften/StringCodecs/Base64.h"
+
+using namespace Swift;
+
+typedef GenericPayloadPersister<DiscoInfo, DiscoInfoParser, DiscoInfoSerializer> DiscoInfoPersister;
+
+CapsFileStorage::CapsFileStorage(const boost::filesystem::path& path) : path(path) {
+}
+
+DiscoInfo::ref CapsFileStorage::getDiscoInfo(const std::string& hash) const {
+	return DiscoInfoPersister().loadPayloadGeneric(getCapsPath(hash));
+}
+
+void CapsFileStorage::setDiscoInfo(const std::string& hash, DiscoInfo::ref discoInfo) {
+	DiscoInfo::ref bareDiscoInfo(new DiscoInfo(*discoInfo.get()));
+	bareDiscoInfo->setNode("");
+	DiscoInfoPersister().savePayload(bareDiscoInfo, getCapsPath(hash));
+}
+
+boost::filesystem::path CapsFileStorage::getCapsPath(const std::string& hash) const {
+	return path / (Hexify::hexify(Base64::decode(hash)) + ".xml");
+}
diff --git a/Swift/Controllers/Storages/CapsFileStorage.h b/Swift/Controllers/Storages/CapsFileStorage.h
new file mode 100644
index 0000000..b3757e0
--- /dev/null
+++ b/Swift/Controllers/Storages/CapsFileStorage.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 <boost/filesystem/path.hpp>
+
+#include "Swiften/Disco/CapsStorage.h"
+#include <string>
+
+namespace Swift {
+	class CapsFileStorage : public CapsStorage {
+		public:
+			CapsFileStorage(const boost::filesystem::path& path);
+
+			virtual DiscoInfo::ref getDiscoInfo(const std::string& hash) const;
+			virtual void setDiscoInfo(const std::string& hash, DiscoInfo::ref discoInfo);
+
+		private:
+			boost::filesystem::path getCapsPath(const std::string& hash) const;
+
+		private:
+			boost::filesystem::path path;
+	};
+}
diff --git a/Swift/Controllers/Storages/CertificateFileStorage.cpp b/Swift/Controllers/Storages/CertificateFileStorage.cpp
new file mode 100644
index 0000000..31af949
--- /dev/null
+++ b/Swift/Controllers/Storages/CertificateFileStorage.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swift/Controllers/Storages/CertificateFileStorage.h>
+
+#include <iostream>
+#include <boost/filesystem/fstream.hpp>
+
+#include <Swiften/StringCodecs/SHA1.h>
+#include <Swiften/StringCodecs/Hexify.h>
+#include <Swiften/TLS/CertificateFactory.h>
+#include <Swiften/Base/Log.h>
+
+namespace Swift {
+
+CertificateFileStorage::CertificateFileStorage(const boost::filesystem::path& path, CertificateFactory* certificateFactory) : path(path), certificateFactory(certificateFactory) {
+}
+
+bool CertificateFileStorage::hasCertificate(Certificate::ref certificate) const {
+	boost::filesystem::path certificatePath = getCertificatePath(certificate);
+	if (boost::filesystem::exists(certificatePath)) {
+		ByteArray data;
+		data.readFromFile(certificatePath.string());
+		Certificate::ref storedCertificate = certificateFactory->createCertificateFromDER(data);
+		if (storedCertificate && storedCertificate->toDER() == certificate->toDER()) {
+			return true;
+		}
+		else {
+			SWIFT_LOG(warning) << "Stored certificate does not match received certificate" << std::endl;
+			return false;
+		}
+	}
+	else {
+		return false;
+	}
+}
+
+void CertificateFileStorage::addCertificate(Certificate::ref certificate) {
+	boost::filesystem::path certificatePath = getCertificatePath(certificate);
+	if (!boost::filesystem::exists(certificatePath.parent_path())) {
+		try {
+			boost::filesystem::create_directories(certificatePath.parent_path());
+		}
+		catch (const boost::filesystem::filesystem_error& e) {
+			std::cerr << "ERROR: " << e.what() << std::endl;
+		}
+	}
+	boost::filesystem::ofstream file(certificatePath, boost::filesystem::ofstream::binary|boost::filesystem::ofstream::out);
+	ByteArray data = certificate->toDER();
+	file.write(reinterpret_cast<const char*>(data.getData()), data.getSize());
+	file.close();
+}
+
+boost::filesystem::path CertificateFileStorage::getCertificatePath(Certificate::ref certificate) const {
+	return path / Hexify::hexify(SHA1::getHash(certificate->toDER()));
+}
+
+}
diff --git a/Swift/Controllers/Storages/CertificateFileStorage.h b/Swift/Controllers/Storages/CertificateFileStorage.h
new file mode 100644
index 0000000..f7a60b9
--- /dev/null
+++ b/Swift/Controllers/Storages/CertificateFileStorage.h
@@ -0,0 +1,31 @@
+/*
+ * 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/filesystem.hpp>
+
+#include "Swift/Controllers/Storages/CertificateStorage.h"
+
+namespace Swift {
+	class CertificateFactory;
+
+	class CertificateFileStorage : public CertificateStorage {
+		public:
+			CertificateFileStorage(const boost::filesystem::path& path, CertificateFactory* certificateFactory);
+
+			virtual bool hasCertificate(Certificate::ref certificate) const;
+			virtual void addCertificate(Certificate::ref certificate);
+
+		private:
+			boost::filesystem::path getCertificatePath(Certificate::ref certificate) const;
+
+		private:
+			boost::filesystem::path path;
+			CertificateFactory* certificateFactory;
+	};
+
+}
diff --git a/Swift/Controllers/Storages/CertificateFileStorageFactory.h b/Swift/Controllers/Storages/CertificateFileStorageFactory.h
new file mode 100644
index 0000000..b215165
--- /dev/null
+++ b/Swift/Controllers/Storages/CertificateFileStorageFactory.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 <Swift/Controllers/Storages/CertificateStorageFactory.h>
+#include <Swift/Controllers/Storages/CertificateFileStorage.h>
+
+namespace Swift {
+	class CertificateFactory;
+
+	class CertificateFileStorageFactory : public CertificateStorageFactory {
+		public:
+			CertificateFileStorageFactory(const boost::filesystem::path& basePath, CertificateFactory* certificateFactory) : basePath(basePath), certificateFactory(certificateFactory) {}
+
+			virtual CertificateStorage* createCertificateStorage(const JID& profile) const {
+				boost::filesystem::path profilePath = basePath / profile.toString();
+				return new CertificateFileStorage(profilePath / "certificates", certificateFactory);
+			}
+
+		private:
+			boost::filesystem::path basePath;
+			CertificateFactory* certificateFactory;
+	};
+}
diff --git a/Swift/Controllers/Storages/CertificateStorage.cpp b/Swift/Controllers/Storages/CertificateStorage.cpp
new file mode 100644
index 0000000..ee942c0
--- /dev/null
+++ b/Swift/Controllers/Storages/CertificateStorage.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 "Swift/Controllers/Storages/CertificateStorage.h"
+
+namespace Swift {
+
+CertificateStorage::~CertificateStorage() {
+}
+
+}
diff --git a/Swift/Controllers/Storages/CertificateStorage.h b/Swift/Controllers/Storages/CertificateStorage.h
new file mode 100644
index 0000000..f8c6fb5
--- /dev/null
+++ b/Swift/Controllers/Storages/CertificateStorage.h
@@ -0,0 +1,22 @@
+/*
+ * 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/filesystem.hpp>
+
+#include <Swiften/TLS/Certificate.h>
+
+namespace Swift {
+	class CertificateStorage {
+		public:
+			virtual ~CertificateStorage();
+
+			virtual bool hasCertificate(Certificate::ref certificate) const = 0;
+			virtual void addCertificate(Certificate::ref certificate) = 0;
+	};
+
+}
diff --git a/Swift/Controllers/Storages/CertificateStorageFactory.cpp b/Swift/Controllers/Storages/CertificateStorageFactory.cpp
new file mode 100644
index 0000000..ba0179a
--- /dev/null
+++ b/Swift/Controllers/Storages/CertificateStorageFactory.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 <Swift/Controllers/Storages/CertificateStorageFactory.h>
+
+namespace Swift {
+
+CertificateStorageFactory::~CertificateStorageFactory() {
+}
+
+}
diff --git a/Swift/Controllers/Storages/CertificateStorageFactory.h b/Swift/Controllers/Storages/CertificateStorageFactory.h
new file mode 100644
index 0000000..5b85757
--- /dev/null
+++ b/Swift/Controllers/Storages/CertificateStorageFactory.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+namespace Swift {
+	class CertificateStorage;
+	class JID;
+
+	class CertificateStorageFactory {
+		public:
+			virtual ~CertificateStorageFactory();
+
+			virtual CertificateStorage* createCertificateStorage(const JID& profile) const = 0;
+	};
+}
diff --git a/Swift/Controllers/Storages/CertificateStorageTrustChecker.h b/Swift/Controllers/Storages/CertificateStorageTrustChecker.h
new file mode 100644
index 0000000..40838dd
--- /dev/null
+++ b/Swift/Controllers/Storages/CertificateStorageTrustChecker.h
@@ -0,0 +1,34 @@
+/*
+ * 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 <Swiften/TLS/CertificateTrustChecker.h>
+#include <Swift/Controllers/Storages/CertificateStorage.h>
+
+namespace Swift {
+	/**
+	 * A certificate trust checker that trusts certificates in a certificate storage.
+	 */
+	class CertificateStorageTrustChecker : public CertificateTrustChecker {
+		public:
+			CertificateStorageTrustChecker(CertificateStorage* storage) : storage(storage) {
+			}
+
+			virtual bool isCertificateTrusted(Certificate::ref certificate) {
+				lastCertificate = certificate;
+				return storage->hasCertificate(certificate);
+			}
+
+			Certificate::ref getLastCertificate() const {
+				return lastCertificate;
+			}
+
+		private:
+			CertificateStorage* storage;
+			Certificate::ref lastCertificate;
+	};
+}
diff --git a/Swift/Controllers/Storages/FileStorages.cpp b/Swift/Controllers/Storages/FileStorages.cpp
new file mode 100644
index 0000000..6447099
--- /dev/null
+++ b/Swift/Controllers/Storages/FileStorages.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include "Swift/Controllers/Storages/FileStorages.h"
+#include "Swift/Controllers/Storages/VCardFileStorage.h"
+#include "Swift/Controllers/Storages/AvatarFileStorage.h"
+#include "Swift/Controllers/Storages/CapsFileStorage.h"
+#include "Swift/Controllers/Storages/RosterFileStorage.h"
+
+namespace Swift {
+
+FileStorages::FileStorages(const boost::filesystem::path& baseDir, const JID& jid) {
+	std::string profile = jid.toBare();
+	vcardStorage = new VCardFileStorage(baseDir / profile / "vcards");
+	capsStorage = new CapsFileStorage(baseDir / "caps");
+	avatarStorage = new AvatarFileStorage(baseDir / "avatars", baseDir / profile / "avatars");
+	rosterStorage = new RosterFileStorage(baseDir / profile / "roster.xml");
+}
+
+FileStorages::~FileStorages() {
+	delete rosterStorage;
+	delete avatarStorage;
+	delete capsStorage;
+	delete vcardStorage;
+}
+
+VCardStorage* FileStorages::getVCardStorage() const {
+	return vcardStorage;
+}
+
+CapsStorage* FileStorages::getCapsStorage() const {
+	return capsStorage;
+}
+
+AvatarStorage* FileStorages::getAvatarStorage() const {
+	return avatarStorage;
+}
+
+RosterStorage* FileStorages::getRosterStorage() const {
+	return rosterStorage;
+}
+
+}
diff --git a/Swift/Controllers/Storages/FileStorages.h b/Swift/Controllers/Storages/FileStorages.h
new file mode 100644
index 0000000..28df314
--- /dev/null
+++ b/Swift/Controllers/Storages/FileStorages.h
@@ -0,0 +1,53 @@
+/*
+ * 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/filesystem/path.hpp>
+
+#include "Swiften/Client/Storages.h"
+
+namespace Swift {
+	class VCardFileStorage;
+	class AvatarFileStorage;
+	class CapsFileStorage;
+	class RosterFileStorage;
+	class JID;
+
+	/**
+	 * A storages implementation that stores all controller data on disk.
+	 */
+	class FileStorages : public Storages {
+		public:
+			/**
+			 * Creates the storages interface.
+			 *
+			 * All data will be stored relative to a base directory, and
+			 * for some controllers, in a subdirectory for the given profile.
+			 * The data is stored in the following places:
+			 * - Avatars: <basedir>/avatars
+			 * - VCards: <basedir>/<profile>/vcards
+			 * - Entity capabilities: <basedir>/caps
+			 *
+			 * \param baseDir the base dir to store data relative to
+			 * \param jid the subdir in which profile-specific data will be stored. 
+			 *   The bare JID will be used as the subdir name.
+			 */
+			FileStorages(const boost::filesystem::path& baseDir, const JID& jid);
+			~FileStorages();
+
+			virtual VCardStorage* getVCardStorage() const;
+			virtual AvatarStorage* getAvatarStorage() const;
+			virtual CapsStorage* getCapsStorage() const;
+			virtual RosterStorage* getRosterStorage() const;
+
+		private:
+			VCardFileStorage* vcardStorage;
+			AvatarFileStorage* avatarStorage;
+			CapsFileStorage* capsStorage;
+			RosterFileStorage* rosterStorage;
+	};
+}
diff --git a/Swift/Controllers/Storages/FileStoragesFactory.h b/Swift/Controllers/Storages/FileStoragesFactory.h
new file mode 100644
index 0000000..75c65b7
--- /dev/null
+++ b/Swift/Controllers/Storages/FileStoragesFactory.h
@@ -0,0 +1,24 @@
+/*
+ * 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 "Swift/Controllers/Storages/StoragesFactory.h"
+#include "Swiften/Client/FileStorages.h"
+
+namespace Swift {
+	class FileStoragesFactory : public StoragesFactory {
+		public:
+			FileStoragesFactory(const boost::filesystem::path& basePath) : basePath(basePath) {}
+
+			virtual Storages* createStorages(const JID& profile) const {
+				return new FileStorages(basePath, profile);
+			}
+
+		private:
+			boost::filesystem::path basePath;
+	};
+}
diff --git a/Swift/Controllers/Storages/MemoryStoragesFactory.h b/Swift/Controllers/Storages/MemoryStoragesFactory.h
new file mode 100644
index 0000000..6648bcd
--- /dev/null
+++ b/Swift/Controllers/Storages/MemoryStoragesFactory.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 "Swift/Controllers/Storages/StoragesFactory.h"
+#include "Swiften/Client/MemoryStorages.h"
+
+namespace Swift {
+	class MemoryStoragesFactory : public StoragesFactory {
+		public:
+			MemoryStoragesFactory() {}
+
+			virtual Storages* createStorages(const JID& profile) const {
+				return new MemoryStorages();
+			}
+	};
+}
diff --git a/Swift/Controllers/Storages/RosterFileStorage.cpp b/Swift/Controllers/Storages/RosterFileStorage.cpp
new file mode 100644
index 0000000..73e582f
--- /dev/null
+++ b/Swift/Controllers/Storages/RosterFileStorage.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swift/Controllers/Storages/RosterFileStorage.h>
+
+#include <Swiften/Entity/GenericPayloadPersister.h>
+#include <Swiften/Serializer/PayloadSerializers/RosterSerializer.h>
+#include <Swiften/Parser/PayloadParsers/RosterParser.h>
+
+using namespace Swift;
+
+typedef GenericPayloadPersister<RosterPayload, RosterParser, RosterSerializer> RosterPersister;
+
+RosterFileStorage::RosterFileStorage(const boost::filesystem::path& path) : path(path) {
+}
+
+boost::shared_ptr<RosterPayload> RosterFileStorage::getRoster() const {
+	return RosterPersister().loadPayloadGeneric(path);
+}
+
+void RosterFileStorage::setRoster(boost::shared_ptr<RosterPayload> roster) {
+	RosterPersister().savePayload(roster, path);
+}
diff --git a/Swift/Controllers/Storages/RosterFileStorage.h b/Swift/Controllers/Storages/RosterFileStorage.h
new file mode 100644
index 0000000..cb00969
--- /dev/null
+++ b/Swift/Controllers/Storages/RosterFileStorage.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/filesystem/path.hpp>
+
+#include <Swiften/Roster/RosterStorage.h>
+
+namespace Swift {
+	class RosterFileStorage : public RosterStorage {
+		public:
+			RosterFileStorage(const boost::filesystem::path& path);
+
+			virtual boost::shared_ptr<RosterPayload> getRoster() const;
+			virtual void setRoster(boost::shared_ptr<RosterPayload>);
+
+		private:
+			boost::filesystem::path path;
+	};
+}
diff --git a/Swift/Controllers/Storages/StoragesFactory.h b/Swift/Controllers/Storages/StoragesFactory.h
new file mode 100644
index 0000000..441a4e9
--- /dev/null
+++ b/Swift/Controllers/Storages/StoragesFactory.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+namespace Swift {
+	class Storages;
+
+	class StoragesFactory {
+		public:
+			virtual ~StoragesFactory() {}
+
+			virtual Storages* createStorages(const JID& profile) const = 0;
+	};
+}
diff --git a/Swift/Controllers/Storages/VCardFileStorage.cpp b/Swift/Controllers/Storages/VCardFileStorage.cpp
new file mode 100644
index 0000000..4933d0c
--- /dev/null
+++ b/Swift/Controllers/Storages/VCardFileStorage.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include "Swift/Controllers/Storages/VCardFileStorage.h"
+
+#include <boost/filesystem/fstream.hpp>
+#include <boost/filesystem.hpp>
+#include <iostream>
+
+#include <Swiften/Entity/GenericPayloadPersister.h>
+#include <Swiften/Base/String.h>
+#include <Swiften/StringCodecs/Hexify.h>
+#include <Swiften/StringCodecs/SHA1.h>
+#include <Swiften/Base/foreach.h>
+#include "Swiften/JID/JID.h"
+#include "Swiften/Elements/VCard.h"
+#include "Swiften/Serializer/PayloadSerializers/VCardSerializer.h"
+#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadParserTester.h"
+#include "Swiften/Parser/PayloadParsers/VCardParser.h"
+
+using namespace Swift;
+
+typedef GenericPayloadPersister<VCard, VCardParser, VCardSerializer> VCardPersister;
+
+VCardFileStorage::VCardFileStorage(boost::filesystem::path dir) : vcardsPath(dir) {
+	cacheFile = vcardsPath / "phashes";
+	if (boost::filesystem::exists(cacheFile)) {
+		try {
+			boost::filesystem::ifstream file(cacheFile);
+			std::string line;
+			if (file.is_open()) {
+				while (!file.eof()) {
+					getline(file, line);
+					std::pair<std::string, std::string> r = String::getSplittedAtFirst(line, ' ');
+					JID jid(r.second);
+					if (jid.isValid()) {
+						photoHashes.insert(std::make_pair(jid, r.first));
+					}
+					else if (!r.first.empty() || !r.second.empty()) {
+						std::cerr << "Invalid entry in phashes file" << std::endl;
+					}
+				}
+			}
+		}
+		catch (...) {
+			std::cerr << "Error reading phashes file" << std::endl;
+		}
+	}
+}
+
+boost::shared_ptr<VCard> VCardFileStorage::getVCard(const JID& jid) const {
+	return VCardPersister().loadPayloadGeneric(getVCardPath(jid));
+}
+
+void VCardFileStorage::setVCard(const JID& jid, VCard::ref v) {
+	VCardPersister().savePayload(v, getVCardPath(jid));
+	getAndUpdatePhotoHash(jid, v);
+}
+
+boost::filesystem::path VCardFileStorage::getVCardPath(const JID& jid) const {
+	std::string file(jid.toString());
+	String::replaceAll(file, '/', "%2f");
+	return boost::filesystem::path(vcardsPath / (file + ".xml"));
+}
+
+std::string VCardFileStorage::getPhotoHash(const JID& jid) const {
+	PhotoHashMap::const_iterator i = photoHashes.find(jid);
+	if (i != photoHashes.end()) {
+		return i->second;
+	}
+	else {
+		VCard::ref vCard = getVCard(jid);
+		return getAndUpdatePhotoHash(jid, vCard);
+	}
+}
+
+std::string VCardFileStorage::getAndUpdatePhotoHash(const JID& jid, VCard::ref vCard) const {
+	std::string hash;
+	if (vCard && !vCard->getPhoto().isEmpty()) {
+		hash = Hexify::hexify(SHA1::getHash(vCard->getPhoto()));
+	}
+	std::pair<PhotoHashMap::iterator, bool> r = photoHashes.insert(std::make_pair(jid, hash));
+	if (r.second) {
+		savePhotoHashes();
+	}
+	else if (r.first->second != hash) {
+		r.first->second = hash;
+		savePhotoHashes();
+	}
+	return hash;
+}
+
+void VCardFileStorage::savePhotoHashes() const {
+	try {
+		boost::filesystem::ofstream file(cacheFile);
+		for (PhotoHashMap::const_iterator i = photoHashes.begin(); i != photoHashes.end(); ++i) {
+			file << i->second << " " << i->first.toString() << std::endl;
+		}
+		file.close();
+	}
+	catch (...) {
+		std::cerr << "Error writing vcards file" << std::endl;
+	}
+}
diff --git a/Swift/Controllers/Storages/VCardFileStorage.h b/Swift/Controllers/Storages/VCardFileStorage.h
new file mode 100644
index 0000000..ba422f4
--- /dev/null
+++ b/Swift/Controllers/Storages/VCardFileStorage.h
@@ -0,0 +1,38 @@
+/*
+ * 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 <boost/filesystem/path.hpp>
+#include <string>
+#include <map>
+
+#include "Swiften/VCards/VCardStorage.h"
+
+namespace Swift {
+	class VCardFileStorage : public VCardStorage {
+		public:
+			VCardFileStorage(boost::filesystem::path dir);
+
+			virtual VCard::ref getVCard(const JID& jid) const;
+			virtual void setVCard(const JID& jid, VCard::ref v);
+
+			virtual std::string getPhotoHash(const JID&) const;
+
+		private:
+			boost::filesystem::path getVCardPath(const JID&) const;
+
+			std::string getAndUpdatePhotoHash(const JID& jid, VCard::ref vcard) const;
+			void savePhotoHashes() const;
+
+		private:
+			boost::filesystem::path vcardsPath;
+			boost::filesystem::path cacheFile;
+			typedef std::map<JID, std::string> PhotoHashMap;
+			mutable PhotoHashMap photoHashes;
+	};
+}
diff --git a/Swift/Controllers/StoragesFactory.h b/Swift/Controllers/StoragesFactory.h
deleted file mode 100644
index 441a4e9..0000000
--- a/Swift/Controllers/StoragesFactory.h
+++ /dev/null
@@ -1,18 +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
-
-namespace Swift {
-	class Storages;
-
-	class StoragesFactory {
-		public:
-			virtual ~StoragesFactory() {}
-
-			virtual Storages* createStorages(const JID& profile) const = 0;
-	};
-}
diff --git a/Swiften/Avatars/AvatarFileStorage.cpp b/Swiften/Avatars/AvatarFileStorage.cpp
deleted file mode 100644
index 9effc16..0000000
--- a/Swiften/Avatars/AvatarFileStorage.cpp
+++ /dev/null
@@ -1,105 +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/Avatars/AvatarFileStorage.h>
-
-#include <iostream>
-#include <boost/filesystem/fstream.hpp>
-#include <boost/filesystem.hpp>
-
-#include <Swiften/Base/foreach.h>
-#include <Swiften/Base/String.h>
-#include <Swiften/StringCodecs/SHA1.h>
-#include <Swiften/StringCodecs/Hexify.h>
-
-namespace Swift {
-
-AvatarFileStorage::AvatarFileStorage(const boost::filesystem::path& avatarsDir, const boost::filesystem::path& avatarsFile) : avatarsDir(avatarsDir), avatarsFile(avatarsFile) {
-	if (boost::filesystem::exists(avatarsFile)) {
-		try {
-			boost::filesystem::ifstream file(avatarsFile);
-			std::string line;
-			if (file.is_open()) {
-				while (!file.eof()) {
-					getline(file, line);
-					std::pair<std::string, std::string> r = String::getSplittedAtFirst(line, ' ');
-					JID jid(r.second);
-					if (jid.isValid()) {
-						jidAvatars.insert(std::make_pair(jid, r.first));
-					}
-					else if (!r.first.empty() || !r.second.empty()) {
-						std::cerr << "Invalid entry in avatars file: " << r.second << std::endl;
-					}
-				}
-			}
-		}
-		catch (...) {
-			std::cerr << "Error reading avatars file" << std::endl;
-		}
-	}
-}
-
-bool AvatarFileStorage::hasAvatar(const std::string& hash) const { 
-	return boost::filesystem::exists(getAvatarPath(hash));
-}
-
-void AvatarFileStorage::addAvatar(const std::string& hash, const ByteArray& avatar) {
-	assert(Hexify::hexify(SHA1::getHash(avatar)) == hash);
-
-	boost::filesystem::path avatarPath = getAvatarPath(hash);
-	if (!boost::filesystem::exists(avatarPath.parent_path())) {
-		try {
-			boost::filesystem::create_directories(avatarPath.parent_path());
-		}
-		catch (const boost::filesystem::filesystem_error& e) {
-			std::cerr << "ERROR: " << e.what() << std::endl;
-		}
-	}
-	boost::filesystem::ofstream file(avatarPath, boost::filesystem::ofstream::binary|boost::filesystem::ofstream::out);
-	file.write(reinterpret_cast<const char*>(avatar.getData()), static_cast<std::streamsize>(avatar.getSize()));
-	file.close();
-}
-
-boost::filesystem::path AvatarFileStorage::getAvatarPath(const std::string& hash) const {
-	return avatarsDir / hash;
-}
-
-ByteArray AvatarFileStorage::getAvatar(const std::string& hash) const {
-	ByteArray data;
-	data.readFromFile(getAvatarPath(hash).string());
-	return data;
-}
-
-void AvatarFileStorage::setAvatarForJID(const JID& jid, const std::string& hash) {
-	std::pair<JIDAvatarMap::iterator, bool> r = jidAvatars.insert(std::make_pair(jid, hash));
-	if (r.second) {
-		saveJIDAvatars();
-	}
-	else if (r.first->second != hash) {
-		r.first->second = hash;
-		saveJIDAvatars();
-	}
-}
-
-std::string AvatarFileStorage::getAvatarForJID(const JID& jid) const {
-	JIDAvatarMap::const_iterator i = jidAvatars.find(jid);
-	return i == jidAvatars.end() ? "" : i->second;
-}
-
-void AvatarFileStorage::saveJIDAvatars() {
-	try {
-		boost::filesystem::ofstream file(avatarsFile);
-		for (JIDAvatarMap::const_iterator i = jidAvatars.begin(); i != jidAvatars.end(); ++i) {
-			file << i->second << " " << i->first.toString() << std::endl;
-		}
-		file.close();
-	}
-	catch (...) {
-		std::cerr << "Error writing avatars file" << std::endl;
-	}
-}
-
-}
diff --git a/Swiften/Avatars/AvatarFileStorage.h b/Swiften/Avatars/AvatarFileStorage.h
deleted file mode 100644
index b7e73f5..0000000
--- a/Swiften/Avatars/AvatarFileStorage.h
+++ /dev/null
@@ -1,41 +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 <string>
-#include <boost/filesystem/path.hpp>
-
-#include <Swiften/JID/JID.h>
-#include "Swiften/Base/ByteArray.h"
-#include "Swiften/Avatars/AvatarStorage.h"
-
-namespace Swift {
-	class AvatarFileStorage : public AvatarStorage {
-		public:
-			AvatarFileStorage(const boost::filesystem::path& avatarsDir, const boost::filesystem::path& avatarsFile);
-
-			virtual bool hasAvatar(const std::string& hash) const;
-			virtual void addAvatar(const std::string& hash, const ByteArray& avatar);
-			virtual ByteArray getAvatar(const std::string& hash) const;
-
-			virtual boost::filesystem::path getAvatarPath(const std::string& hash) const;
-
-			virtual void setAvatarForJID(const JID& jid, const std::string& hash);
-			virtual std::string getAvatarForJID(const JID& jid) const;
-
-		private:
-			void saveJIDAvatars();
-
-		private:
-			boost::filesystem::path avatarsDir;
-			boost::filesystem::path avatarsFile;
-			typedef std::map<JID, std::string> JIDAvatarMap;
-			JIDAvatarMap jidAvatars;
-	};
-
-}
diff --git a/Swiften/Avatars/SConscript b/Swiften/Avatars/SConscript
index 46ae897..9c219a4 100644
--- a/Swiften/Avatars/SConscript
+++ b/Swiften/Avatars/SConscript
@@ -1,7 +1,6 @@
 Import("swiften_env")
 
 objects = swiften_env.SwiftenObject([
-			"AvatarFileStorage.cpp",
 			"VCardUpdateAvatarManager.cpp",
 			"VCardAvatarManager.cpp",
 			"OfflineAvatarManager.cpp",
diff --git a/Swiften/Client/FileStorages.cpp b/Swiften/Client/FileStorages.cpp
deleted file mode 100644
index e6a93fd..0000000
--- a/Swiften/Client/FileStorages.cpp
+++ /dev/null
@@ -1,46 +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/Client/FileStorages.h"
-#include "Swiften/VCards/VCardFileStorage.h"
-#include "Swiften/Avatars/AvatarFileStorage.h"
-#include "Swiften/Disco/CapsFileStorage.h"
-#include "Swiften/Roster/RosterFileStorage.h"
-
-namespace Swift {
-
-FileStorages::FileStorages(const boost::filesystem::path& baseDir, const JID& jid) {
-	std::string profile = jid.toBare();
-	vcardStorage = new VCardFileStorage(baseDir / profile / "vcards");
-	capsStorage = new CapsFileStorage(baseDir / "caps");
-	avatarStorage = new AvatarFileStorage(baseDir / "avatars", baseDir / profile / "avatars");
-	rosterStorage = new RosterFileStorage(baseDir / profile / "roster.xml");
-}
-
-FileStorages::~FileStorages() {
-	delete rosterStorage;
-	delete avatarStorage;
-	delete capsStorage;
-	delete vcardStorage;
-}
-
-VCardStorage* FileStorages::getVCardStorage() const {
-	return vcardStorage;
-}
-
-CapsStorage* FileStorages::getCapsStorage() const {
-	return capsStorage;
-}
-
-AvatarStorage* FileStorages::getAvatarStorage() const {
-	return avatarStorage;
-}
-
-RosterStorage* FileStorages::getRosterStorage() const {
-	return rosterStorage;
-}
-
-}
diff --git a/Swiften/Client/FileStorages.h b/Swiften/Client/FileStorages.h
deleted file mode 100644
index 28df314..0000000
--- a/Swiften/Client/FileStorages.h
+++ /dev/null
@@ -1,53 +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/filesystem/path.hpp>
-
-#include "Swiften/Client/Storages.h"
-
-namespace Swift {
-	class VCardFileStorage;
-	class AvatarFileStorage;
-	class CapsFileStorage;
-	class RosterFileStorage;
-	class JID;
-
-	/**
-	 * A storages implementation that stores all controller data on disk.
-	 */
-	class FileStorages : public Storages {
-		public:
-			/**
-			 * Creates the storages interface.
-			 *
-			 * All data will be stored relative to a base directory, and
-			 * for some controllers, in a subdirectory for the given profile.
-			 * The data is stored in the following places:
-			 * - Avatars: <basedir>/avatars
-			 * - VCards: <basedir>/<profile>/vcards
-			 * - Entity capabilities: <basedir>/caps
-			 *
-			 * \param baseDir the base dir to store data relative to
-			 * \param jid the subdir in which profile-specific data will be stored. 
-			 *   The bare JID will be used as the subdir name.
-			 */
-			FileStorages(const boost::filesystem::path& baseDir, const JID& jid);
-			~FileStorages();
-
-			virtual VCardStorage* getVCardStorage() const;
-			virtual AvatarStorage* getAvatarStorage() const;
-			virtual CapsStorage* getCapsStorage() const;
-			virtual RosterStorage* getRosterStorage() const;
-
-		private:
-			VCardFileStorage* vcardStorage;
-			AvatarFileStorage* avatarStorage;
-			CapsFileStorage* capsStorage;
-			RosterFileStorage* rosterStorage;
-	};
-}
diff --git a/Swiften/Disco/CapsFileStorage.cpp b/Swiften/Disco/CapsFileStorage.cpp
deleted file mode 100644
index 81e9551..0000000
--- a/Swiften/Disco/CapsFileStorage.cpp
+++ /dev/null
@@ -1,34 +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/Disco/CapsFileStorage.h"
-
-#include <Swiften/Entity/GenericPayloadPersister.h>
-#include "Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.h"
-#include "Swiften/Parser/PayloadParsers/DiscoInfoParser.h"
-#include "Swiften/StringCodecs/Hexify.h"
-#include "Swiften/StringCodecs/Base64.h"
-
-using namespace Swift;
-
-typedef GenericPayloadPersister<DiscoInfo, DiscoInfoParser, DiscoInfoSerializer> DiscoInfoPersister;
-
-CapsFileStorage::CapsFileStorage(const boost::filesystem::path& path) : path(path) {
-}
-
-DiscoInfo::ref CapsFileStorage::getDiscoInfo(const std::string& hash) const {
-	return DiscoInfoPersister().loadPayloadGeneric(getCapsPath(hash));
-}
-
-void CapsFileStorage::setDiscoInfo(const std::string& hash, DiscoInfo::ref discoInfo) {
-	DiscoInfo::ref bareDiscoInfo(new DiscoInfo(*discoInfo.get()));
-	bareDiscoInfo->setNode("");
-	DiscoInfoPersister().savePayload(bareDiscoInfo, getCapsPath(hash));
-}
-
-boost::filesystem::path CapsFileStorage::getCapsPath(const std::string& hash) const {
-	return path / (Hexify::hexify(Base64::decode(hash)) + ".xml");
-}
diff --git a/Swiften/Disco/CapsFileStorage.h b/Swiften/Disco/CapsFileStorage.h
deleted file mode 100644
index b3757e0..0000000
--- a/Swiften/Disco/CapsFileStorage.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 <boost/filesystem/path.hpp>
-
-#include "Swiften/Disco/CapsStorage.h"
-#include <string>
-
-namespace Swift {
-	class CapsFileStorage : public CapsStorage {
-		public:
-			CapsFileStorage(const boost::filesystem::path& path);
-
-			virtual DiscoInfo::ref getDiscoInfo(const std::string& hash) const;
-			virtual void setDiscoInfo(const std::string& hash, DiscoInfo::ref discoInfo);
-
-		private:
-			boost::filesystem::path getCapsPath(const std::string& hash) const;
-
-		private:
-			boost::filesystem::path path;
-	};
-}
diff --git a/Swiften/Disco/SConscript b/Swiften/Disco/SConscript
index a4b47db..434018a 100644
--- a/Swiften/Disco/SConscript
+++ b/Swiften/Disco/SConscript
@@ -7,7 +7,6 @@ objects = swiften_env.SwiftenObject([
 			"EntityCapsProvider.cpp",
 			"DummyEntityCapsProvider.cpp",
 			"CapsStorage.cpp",
-			"CapsFileStorage.cpp",
 			"ClientDiscoManager.cpp",
 			"DiscoInfoResponder.cpp",
 			"JIDDiscoInfoResponder.cpp",
diff --git a/Swiften/Roster/RosterFileStorage.cpp b/Swiften/Roster/RosterFileStorage.cpp
deleted file mode 100644
index 31b6c5e..0000000
--- a/Swiften/Roster/RosterFileStorage.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2011 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#include <Swiften/Roster/RosterFileStorage.h>
-
-#include <Swiften/Entity/GenericPayloadPersister.h>
-#include <Swiften/Serializer/PayloadSerializers/RosterSerializer.h>
-#include <Swiften/Parser/PayloadParsers/RosterParser.h>
-
-using namespace Swift;
-
-typedef GenericPayloadPersister<RosterPayload, RosterParser, RosterSerializer> RosterPersister;
-
-RosterFileStorage::RosterFileStorage(const boost::filesystem::path& path) : path(path) {
-}
-
-boost::shared_ptr<RosterPayload> RosterFileStorage::getRoster() const {
-	return RosterPersister().loadPayloadGeneric(path);
-}
-
-void RosterFileStorage::setRoster(boost::shared_ptr<RosterPayload> roster) {
-	RosterPersister().savePayload(roster, path);
-}
diff --git a/Swiften/Roster/RosterFileStorage.h b/Swiften/Roster/RosterFileStorage.h
deleted file mode 100644
index cb00969..0000000
--- a/Swiften/Roster/RosterFileStorage.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2011 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#pragma once
-
-#include <boost/filesystem/path.hpp>
-
-#include <Swiften/Roster/RosterStorage.h>
-
-namespace Swift {
-	class RosterFileStorage : public RosterStorage {
-		public:
-			RosterFileStorage(const boost::filesystem::path& path);
-
-			virtual boost::shared_ptr<RosterPayload> getRoster() const;
-			virtual void setRoster(boost::shared_ptr<RosterPayload>);
-
-		private:
-			boost::filesystem::path path;
-	};
-}
diff --git a/Swiften/SConscript b/Swiften/SConscript
index 5536b3f..41de5b5 100644
--- a/Swiften/SConscript
+++ b/Swiften/SConscript
@@ -58,7 +58,6 @@ if env["SCONS_STAGE"] == "build" :
 			"Client/ClientXMLTracer.cpp",
 			"Client/ClientSession.cpp",
 			"Client/MemoryStorages.cpp",
-			"Client/FileStorages.cpp",
 			"Client/NickResolver.cpp",
 			"Client/NickManager.cpp",
 			"Client/NickManagerImpl.cpp",
@@ -97,7 +96,6 @@ if env["SCONS_STAGE"] == "build" :
 			"Queries/Responders/SoftwareVersionResponder.cpp",
 			"Roster/RosterStorage.cpp",
 			"Roster/RosterMemoryStorage.cpp",
-			"Roster/RosterFileStorage.cpp",
 			"Roster/XMPPRoster.cpp",
 			"Roster/XMPPRosterImpl.cpp",
 			"Roster/XMPPRosterController.cpp",
diff --git a/Swiften/VCards/SConscript b/Swiften/VCards/SConscript
index e980ba3..c20c17d 100644
--- a/Swiften/VCards/SConscript
+++ b/Swiften/VCards/SConscript
@@ -3,6 +3,5 @@ Import("swiften_env")
 objects = swiften_env.SwiftenObject([
 			"VCardManager.cpp",
 			"VCardStorage.cpp",
-			"VCardFileStorage.cpp",
 		])
 swiften_env.Append(SWIFTEN_OBJECTS = [objects])
diff --git a/Swiften/VCards/VCardFileStorage.cpp b/Swiften/VCards/VCardFileStorage.cpp
deleted file mode 100644
index 1b23635..0000000
--- a/Swiften/VCards/VCardFileStorage.cpp
+++ /dev/null
@@ -1,107 +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/VCards/VCardFileStorage.h"
-
-#include <boost/filesystem/fstream.hpp>
-#include <boost/filesystem.hpp>
-#include <iostream>
-
-#include <Swiften/Entity/GenericPayloadPersister.h>
-#include <Swiften/Base/String.h>
-#include <Swiften/StringCodecs/Hexify.h>
-#include <Swiften/StringCodecs/SHA1.h>
-#include <Swiften/Base/foreach.h>
-#include "Swiften/JID/JID.h"
-#include "Swiften/Elements/VCard.h"
-#include "Swiften/Serializer/PayloadSerializers/VCardSerializer.h"
-#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadParserTester.h"
-#include "Swiften/Parser/PayloadParsers/VCardParser.h"
-
-using namespace Swift;
-
-typedef GenericPayloadPersister<VCard, VCardParser, VCardSerializer> VCardPersister;
-
-VCardFileStorage::VCardFileStorage(boost::filesystem::path dir) : vcardsPath(dir) {
-	cacheFile = vcardsPath / "phashes";
-	if (boost::filesystem::exists(cacheFile)) {
-		try {
-			boost::filesystem::ifstream file(cacheFile);
-			std::string line;
-			if (file.is_open()) {
-				while (!file.eof()) {
-					getline(file, line);
-					std::pair<std::string, std::string> r = String::getSplittedAtFirst(line, ' ');
-					JID jid(r.second);
-					if (jid.isValid()) {
-						photoHashes.insert(std::make_pair(jid, r.first));
-					}
-					else if (!r.first.empty() || !r.second.empty()) {
-						std::cerr << "Invalid entry in phashes file" << std::endl;
-					}
-				}
-			}
-		}
-		catch (...) {
-			std::cerr << "Error reading phashes file" << std::endl;
-		}
-	}
-}
-
-boost::shared_ptr<VCard> VCardFileStorage::getVCard(const JID& jid) const {
-	return VCardPersister().loadPayloadGeneric(getVCardPath(jid));
-}
-
-void VCardFileStorage::setVCard(const JID& jid, VCard::ref v) {
-	VCardPersister().savePayload(v, getVCardPath(jid));
-	getAndUpdatePhotoHash(jid, v);
-}
-
-boost::filesystem::path VCardFileStorage::getVCardPath(const JID& jid) const {
-	std::string file(jid.toString());
-	String::replaceAll(file, '/', "%2f");
-	return boost::filesystem::path(vcardsPath / (file + ".xml"));
-}
-
-std::string VCardFileStorage::getPhotoHash(const JID& jid) const {
-	PhotoHashMap::const_iterator i = photoHashes.find(jid);
-	if (i != photoHashes.end()) {
-		return i->second;
-	}
-	else {
-		VCard::ref vCard = getVCard(jid);
-		return getAndUpdatePhotoHash(jid, vCard);
-	}
-}
-
-std::string VCardFileStorage::getAndUpdatePhotoHash(const JID& jid, VCard::ref vCard) const {
-	std::string hash;
-	if (vCard && !vCard->getPhoto().isEmpty()) {
-		hash = Hexify::hexify(SHA1::getHash(vCard->getPhoto()));
-	}
-	std::pair<PhotoHashMap::iterator, bool> r = photoHashes.insert(std::make_pair(jid, hash));
-	if (r.second) {
-		savePhotoHashes();
-	}
-	else if (r.first->second != hash) {
-		r.first->second = hash;
-		savePhotoHashes();
-	}
-	return hash;
-}
-
-void VCardFileStorage::savePhotoHashes() const {
-	try {
-		boost::filesystem::ofstream file(cacheFile);
-		for (PhotoHashMap::const_iterator i = photoHashes.begin(); i != photoHashes.end(); ++i) {
-			file << i->second << " " << i->first.toString() << std::endl;
-		}
-		file.close();
-	}
-	catch (...) {
-		std::cerr << "Error writing vcards file" << std::endl;
-	}
-}
diff --git a/Swiften/VCards/VCardFileStorage.h b/Swiften/VCards/VCardFileStorage.h
deleted file mode 100644
index ba422f4..0000000
--- a/Swiften/VCards/VCardFileStorage.h
+++ /dev/null
@@ -1,38 +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 <boost/filesystem/path.hpp>
-#include <string>
-#include <map>
-
-#include "Swiften/VCards/VCardStorage.h"
-
-namespace Swift {
-	class VCardFileStorage : public VCardStorage {
-		public:
-			VCardFileStorage(boost::filesystem::path dir);
-
-			virtual VCard::ref getVCard(const JID& jid) const;
-			virtual void setVCard(const JID& jid, VCard::ref v);
-
-			virtual std::string getPhotoHash(const JID&) const;
-
-		private:
-			boost::filesystem::path getVCardPath(const JID&) const;
-
-			std::string getAndUpdatePhotoHash(const JID& jid, VCard::ref vcard) const;
-			void savePhotoHashes() const;
-
-		private:
-			boost::filesystem::path vcardsPath;
-			boost::filesystem::path cacheFile;
-			typedef std::map<JID, std::string> PhotoHashMap;
-			mutable PhotoHashMap photoHashes;
-	};
-}
-- 
cgit v0.10.2-6-g49f6