diff --git a/source/dub/dependency.d b/source/dub/dependency.d
index 0f31bbe..35ee162 100644
--- a/source/dub/dependency.d
+++ b/source/dub/dependency.d
@@ -238,6 +238,24 @@
 			&& o.m_versA == m_versA && o.m_versB == m_versB 
 			&& o.m_optional == m_optional;
 	}
+
+	int opCmp(in Dependency o)
+	const {
+		if (m_cmpA != o.m_cmpA) return m_cmpA < o.m_cmpA ? -1 : 1;
+		if (m_cmpB != o.m_cmpB) return m_cmpB < o.m_cmpB ? -1 : 1;
+		if (m_versA != o.m_versA) return m_versA < o.m_versA ? -1 : 1;
+		if (m_versB != o.m_versB) return m_versB < o.m_versB ? -1 : 1;
+		if (m_optional != o.m_optional) return m_optional ? -1 : 1;
+		return 0;
+	}
+
+	hash_t toHash() const nothrow @trusted  {
+		try {
+			auto strhash = &typeid(string).getHash;
+			auto str = this.toString();
+			return strhash(&str);
+		} catch assert(false);
+	}
 	
 	bool valid() const {
 		return m_versA == m_versB // compare not important
diff --git a/source/dub/dependencyresolver.d b/source/dub/dependencyresolver.d
index 2a50374..f8b5ac3 100644
--- a/source/dub/dependencyresolver.d
+++ b/source/dub/dependencyresolver.d
@@ -21,11 +21,39 @@
 	static struct TreeNodes {
 		string pack;
 		CONFIGS configs;
+
+		hash_t toHash() const nothrow @trusted {
+			try {
+				size_t ret = typeid(string).getHash(&pack);
+				ret ^= typeid(CONFIGS).getHash(&configs);
+				return ret;
+			} catch assert(false);
+		}
+		bool opEqual(in ref TreeNodes other) const { return pack == other.pack && configs == other.configs; }
+		int opCmp(in ref TreeNodes other) const {
+			if (pack != other.pack) return pack < other.pack ? -1 : 1;
+			if (configs != other.configs) return configs < other.configs ? -1 : 1;
+			return 0;
+		}
 	}
 
 	static struct TreeNode {
 		string pack;
 		CONFIG config;
+
+		hash_t toHash() const nothrow @trusted {
+			try {
+				size_t ret = typeid(string).getHash(&pack);
+				ret ^= typeid(CONFIG).getHash(&config);
+				return ret;
+			} catch assert(false);
+		}
+		bool opEqual(in ref TreeNode other) const { return pack == other.pack && config == other.config; }
+		int opCmp(in ref TreeNode other) const {
+			if (pack != other.pack) return pack < other.pack ? -1 : 1;
+			if (config != other.config) return config < other.config ? -1 : 1;
+			return 0;
+		}
 	}
 
 	CONFIG[string] resolve(TreeNode root, bool throw_on_failure = true)