 //  Copyright (c) 2014 Robert Widmann. All rights reserved.
 //
 
-
-public func protectResults(rs: Rose<TestResult>) -> Rose<TestResult> {
+infix operator • {
+	precedence 190
+	associativity right
+}
+
+public func conjoin(ps : [Testable]) -> Property {
+	return Property(sequence(ps.map({ (p : Testable) in
+		return p.property().unProperty.fmap({ $0.unProp })
+	})).bind({ roses in
+		return Gen.pure(Prop(unProp: conj(id, roses)))
+	}))
+}
+
+public func disjoin(ps : [Testable]) -> Property {
+	return Property(sequence(ps.map({ (p : Testable) in
+		return p.property().unProperty.fmap({ $0.unProp })
+	})).bind({ roses in
+		return Gen.pure(Prop(unProp: roses.reduce(.MkRose({ failed() }, { [] }), combine: disj)))
+	}))
+}
+
+public func protectResults(rs : Rose<TestResult>) -> Rose<TestResult> {
 	return onRose({ x in
 		return { rs in
 			return .MkRose({ x }, { rs.map(protectResults) })

		map.updateValue(v, forKey: k)
	}
	return map
}

public enum Callback {

	return p.property()
}

private func id<A>(x : A) -> A {
	return x
}

private func • <A, B, C>(f : B -> C, g : A -> B) -> A -> C {
	return { f(g($0)) }
}

internal func insertWith<K : Hashable, V>(f : (V, V) -> V, k : K, v : V, var m : Dictionary<K, V>) -> Dictionary<K, V> {
	let oldV = m[k]
	if let existV = oldV {
