Index: src/uk/me/parabola/mkgmap/osmstyle/RuleIndex.java
===================================================================
--- src/uk/me/parabola/mkgmap/osmstyle/RuleIndex.java	(revision 4183)
+++ src/uk/me/parabola/mkgmap/osmstyle/RuleIndex.java	(working copy)
@@ -27,7 +27,6 @@
 import uk.me.parabola.mkgmap.osmstyle.eval.Op;
 import uk.me.parabola.mkgmap.reader.osm.Rule;
 import uk.me.parabola.mkgmap.reader.osm.TagDict;
-import uk.me.parabola.util.MultiHashMap;
 
 /**
  * An index to reduce the number of rules that have to be executed.
@@ -72,21 +71,21 @@
 	private boolean inited;
 
 	private class TagHelper{
-		// This is an index of all rules that start with EXISTS (A=*) or (A=B)
-		final BitSet checked;
+		// This is an index of all rules that start with EXISTS (A=*)
+		final BitSet exists;
 		// This is an index of all rules that start with EQUALS (A=B) 
 		Map<String, BitSet> tagVals;
 		
-		public TagHelper(BitSet checked){
-			this.checked = checked;
+		public TagHelper(BitSet exits){
+			this.exists = exits;
 		}
 
 		public void addTag(String val, BitSet value) {
 			if (tagVals == null)
 				tagVals = new HashMap<>();
-			if (checked != null){	
+			if (exists != null){	
 				BitSet merged = new BitSet();
-				merged.or(checked);
+				merged.or(exists);
 				merged.or(value);
 				tagVals.put(val, merged);
 			} else
@@ -100,8 +99,8 @@
 					return (BitSet) set.clone();
 				}
 			} 
-			if (checked != null)
-				return (BitSet) checked.clone();
+			if (exists != null)
+				return (BitSet) exists.clone();
 			return new BitSet();
 		}
 	}
@@ -163,6 +162,8 @@
 	public void prepare() {
 		if (inited)
 			return;
+		// This is an index of all rules that start with EXISTS (A=*)
+		Map<String, BitSet> existKeys = new HashMap<String, BitSet>();
 		// This is an index of all rules that start with EQUALS (A=B)
 		Map<String, BitSet> tagVals = new HashMap<String, BitSet>();
 		
@@ -172,14 +173,6 @@
 		// Maps a rule number to the tags that might be changed by that rule
 		Map<Integer, List<String>> changeTags = new HashMap<Integer, List<String>>();
 		
-		// Collection of possibly changed or added tags were the new value is
-		// NOT known (e.g. set x=$y)
-		Set<String> modOrAddedTagKeys = new HashSet<>();
-
-		// Collection of possibly changed or added tags were the new value is
-		// known (e.g. set x=1)
-		MultiHashMap<String, String> modOrAddedTags = new MultiHashMap<>();
-
 		// remove unnecessary rules
 		filterRules();
 
@@ -191,32 +184,20 @@
 
 			if (keystring.endsWith("=*")) {
 				String key = keystring.substring(0, keystring.length() - 2);
+				addNumberToMap(existKeys, key, ruleNumber);
 				addNumberToMap(tagnames, key, ruleNumber);
 			} else {
 				addNumberToMap(tagVals, keystring, ruleNumber);
-				// check if any of the previous rules may have changed the tag
 				int ind = keystring.indexOf('=');
-				assert ind >= 0 : "rule index: error in keystring " + keystring; 
-				String key = keystring.substring(0, ind);
-				boolean needed = (modOrAddedTagKeys.contains(key));
-				if (!needed) {
-					List<String> values = modOrAddedTags.get(key);
-					if (values.contains(keystring.substring(ind + 1)))
-						needed = true;
-				}
-				if (needed) {
+				if (ind >= 0) {
+					String key = keystring.substring(0, ind);
 					addNumberToMap(tagnames, key, ruleNumber);
+				} else {
+					assert false: "rule index: no = in keystring " + keystring;	
 				}
+					
 			}
 			addChangables(changeTags, changeableTags, ruleNumber);
-			for (String ent : changeableTags) {
-				int ind = ent.indexOf('=');
-				if (ind >= 0) {
-					modOrAddedTags.add(ent.substring(0, ind), ent.substring(ind + 1));
-				} else {
-					modOrAddedTagKeys.add(ent);
-				}
-			}
 		}
 		
 		for (Map.Entry<Integer, List<String>> ent : changeTags.entrySet()) {
@@ -237,8 +218,17 @@
 					// rule using the tag, no matter what the value.
 					int ind = s.indexOf('=');
 					if (ind >= 0) {
+						set = tagVals.get(s);
+
+						// Exists rules can also be triggered, so add them too.
 						String key = s.substring(0, ind);
-						set = tagnames.get(key);
+						BitSet set1 = existKeys.get(key);
+
+						if (set == null)
+							set = set1;
+						else if (set1 != null)
+							set.or(set1);
+
 					} else {
 						set = tagnames.get(s);
 					}
@@ -260,7 +250,7 @@
 
 						// Find every rule number set that contains the rule number that we
 						// are examining and add all the newly found rules to each such set.
-						for (Map<String, BitSet> m : Arrays.asList(tagVals, tagnames)) {
+						for (Map<String, BitSet> m : Arrays.asList(existKeys, tagVals, tagnames)) {
 							Collection<BitSet> bitSets = m.values();
 							for (BitSet bi : bitSets) {
 								if (bi.get(ruleNumber)) {
@@ -279,7 +269,7 @@
 		}
 
 		// compress the index: create one hash map with one entry for each key
-		for (Map.Entry<String, BitSet> entry  : tagnames.entrySet()){
+		for (Map.Entry<String, BitSet> entry  : existKeys.entrySet()){
 			Short skey = TagDict.getInstance().xlate(entry.getKey());
 			tagKeyMap.put(skey, new TagHelper(entry.getValue()));
 		}
