diff --git a/libwccl/values/strset.cpp b/libwccl/values/strset.cpp
index 4823999e83064837b99714dc68a50795f8330be3..ed6b4bc436afedf9f961c7dc76158237c2cc61e5 100644
--- a/libwccl/values/strset.cpp
+++ b/libwccl/values/strset.cpp
@@ -11,15 +11,46 @@ const char* StrSet::type_name = "StrSet";
 std::string StrSet::to_raw_string() const
 {
 	std::stringstream ss;
-	ss << "{";
-	bool comma = false;
-	foreach (const UnicodeString& u, set_) {
-		if (comma) {
-			ss << ",";
+	ss << "[";
+	set_t::const_iterator it = set_.begin();
+	while(it != set_.end()) {
+		ss << '\"' << PwrNlp::to_utf8(*it) << '\"'; //TODO escaping
+		if(++it != set_.end()) {
+			ss << ", ";
 		}
-		ss << '\"' << PwrNlp::to_utf8(u) << '\"'; //TODO escaping
 	}
+	ss << "]";
 	return ss.str();
 }
 
+bool StrSet::intersects(const StrSet &other) const {
+	if(empty() || other.empty()) {
+		return false;
+	}
+	//we just want to check if there is an intersection, no
+	//need to actually compute it to check if it's empty.
+	//doing it like below sounds faster than, say, sorting
+	//the sets and using set_intersection
+	const set_t& smaller = size() < other.size() ? set_ : other.set_;
+	const set_t& bigger = size() < other.size() ? other.set_ : set_;
+	foreach (const UnicodeString& u, smaller) {
+		if(bigger.find(u) != bigger.end()) {
+			return true;
+		}
+	}
+	return false;
+}
+
+bool StrSet::is_subset_of(const StrSet &other) const {
+	if(empty() || size() > other.size()) {
+		return false;
+	}
+	foreach (const UnicodeString& u, set_) {
+		if(other.set_.find(u) == other.set_.end()) {
+			return false;
+		}
+	}
+	return true;
+}
+
 } /* end ns Wccl */
diff --git a/libwccl/values/strset.h b/libwccl/values/strset.h
index ec6b48f49fa2ee053e798ef00afabcf3ba6a6d9e..e984bd052d7009ad7b1d0c81a7c5381eb3547da2 100644
--- a/libwccl/values/strset.h
+++ b/libwccl/values/strset.h
@@ -56,19 +56,12 @@ public:
 		return set_.empty();
 	}
 
-	bool is_subset_of(const StrSet& /*set*/) const {
-		//TODO: implement this
-		return false;
-	}
+	bool is_subset_of(const StrSet& other) const;
 
-	bool intersects(const StrSet& /*set*/) const {
-		//TODO: implement this
-		return false;
-	}
+	bool intersects(const StrSet& other) const;
 
-	bool equals(const StrSet& /*set*/) const {
-		//TODO: implement this
-		return false;
+	bool equals(const StrSet& other) const {
+		return set_ == other.set_;
 	}
 
 	/// Value override