docs: function(objA, objB) {
  		// first see if we can union a single property
  		// {age: 21, color: ["R"]} U {age: 21, color: ["B"]} -> {age: 21, color: ["R","B"]}
  
  		var diff = keyDiff(objA.values, objB.values);
  
  
  		// find the different keys
  		var aAndBKeysThatAreNotEqual = [],
  			sameKeys = {};
  
  		diff.aAndBKeys.forEach(function(key) {
  			if (!set.isEqual(objA.values[key], objB.values[key])) {
  				aAndBKeysThatAreNotEqual.push(key)
  			} else {
  				sameKeys[key] = objA.values[key];
  			}
  		});
  		var aUnequal = {}, bUnequal = {};
  		aAndBKeysThatAreNotEqual.forEach(function(key){
  			aUnequal[key] = objA.values[key];
  			bUnequal[key] = objB.values[key];
  		});
  
  		// if all keys are shared
  		if (!diff.aOnlyKeys.length && !diff.bOnlyKeys.length) {
  
  			if (aAndBKeysThatAreNotEqual.length === 1) {
  				var keyValue = aAndBKeysThatAreNotEqual[0];
  
  				var result = sameKeys[keyValue] = set.union(objA.values[keyValue], objB.values[keyValue]);
  
  				// if there is only one property, we can just return the universal set
  				return canReflect.size(sameKeys) === 1 && set.isEqual(result, set.UNIVERSAL) ?
  					set.UNIVERSAL : new KeysAnd(sameKeys);
  			} else if (aAndBKeysThatAreNotEqual.length === 0) {
  				// these things are equal
  				return objA;
  			}
  		}
  		// If everything shared is the same
  		if (aAndBKeysThatAreNotEqual.length === 0) {
  			// the set with the extra keys is a subset
  			if (diff.aOnlyKeys.length > 0 && diff.bOnlyKeys.length === 0) {
  				return checkIfUniversalAndReturnUniversal(objB);
  			} else if (diff.aOnlyKeys.length === 0 && diff.bOnlyKeys.length > 0) {
  				return checkIfUniversalAndReturnUniversal(objA);
  			}
  		}
  		// (count > 5 && age > 25 ) || (count > 7 && age > 35 && name > "Justin" )
  		//
  		// ( age > 25 ) || ( name > "Justin" && age > 35)  A U (B & C) => (A U B) & (A U C)
  		// ( age > 25 || name > "Justin" ) && (age > 25)
  		// lets see if one side is different
  		if (diff.aOnlyKeys.length > 0 && diff.bOnlyKeys.length === 0) {
  			// collect shared value
  			if( set.isSubset(new KeysAnd(aUnequal), new KeysAnd(bUnequal) )) {
  				return objB;
  			}
  		}
  		if (diff.bOnlyKeys.length > 0 && diff.aOnlyKeys.length === 0) {
  			// collect shared value
  			if( set.isSubset(new KeysAnd(bUnequal),  new KeysAnd(aUnequal) )) {
  				return objA;
  			}
  		}
  
  		return new keysLogic.ValuesOr([objA, objB]);
  	}