Index: src/uk/me/parabola/mkgmap/main/StyleTester.java
===================================================================
--- src/uk/me/parabola/mkgmap/main/StyleTester.java	(revision 3354)
+++ src/uk/me/parabola/mkgmap/main/StyleTester.java	(working copy)
@@ -670,6 +670,11 @@
 					rule.setFinalizeRule(finalizeRule);
 				}
 			}
+
+			@Override
+			public void printStats(String header) {
+				// TODO Auto-generated method stub
+			}
 		}
 
 		/**
Index: src/uk/me/parabola/mkgmap/osmstyle/ActionRule.java
===================================================================
--- src/uk/me/parabola/mkgmap/osmstyle/ActionRule.java	(revision 3354)
+++ src/uk/me/parabola/mkgmap/osmstyle/ActionRule.java	(working copy)
@@ -18,6 +18,7 @@
 
 import java.util.List;
 
+import uk.me.parabola.log.Logger;
 import uk.me.parabola.mkgmap.osmstyle.actions.Action;
 import uk.me.parabola.mkgmap.osmstyle.eval.Op;
 import uk.me.parabola.mkgmap.reader.osm.Element;
@@ -36,10 +37,13 @@
  * @author Steve Ratcliffe
  */
 public class ActionRule implements Rule {
+	private static final Logger statsLog = Logger.getLogger(ActionRule.class.getPackage().getName()+".stats");
 	private Op expression;
 	private final List<Action> actions;
 	private final GType type;
 	private Rule finalizeRule;
+	private long numEval; // count how often the expression was evaluated 
+	private long numTrue; // count how often the evaluation returned true
 
 	/** Finalize rules must not have an element type definition so the add method must never be called. */
 	private final static TypeResult finalizeTypeResult = new TypeResult() {
@@ -66,9 +70,10 @@
 	public int resolveType(int cacheId, Element el, TypeResult result) {
 		Element element = el;
 		if (expression != null) {
+			numEval++;
 			if (!expression.eval(cacheId, element))
 				return cacheId;
-				
+			numTrue++;
 			// If this is a continue and we are not to propagate the effects
 			// of the action on the element to further rules, then make
 			// a copy of the element so that the original is unsullied.
@@ -108,8 +113,10 @@
 	public void resolveType(Element el, TypeResult result) {
 		Element element = el;
 		if (expression != null) {
+			numEval++;
 			if (!expression.eval(element))
 				return;
+			numTrue++;
 			// If this is a continue and we are not to propagate the effects
 			// of the action on the element to further rules, then make
 			// a copy of the element so that the original is unsullied.
@@ -168,4 +175,9 @@
 		this.expression = expression;
 	}
 	
+	@Override
+	public void printStats(String header) {
+		if (statsLog.isInfoEnabled())
+			statsLog.info(header,"stats (rule/evals/true)", this.toString() + "/" + numEval + "/" + numTrue);
+	}
 }
Index: src/uk/me/parabola/mkgmap/osmstyle/ExpressionRule.java
===================================================================
--- src/uk/me/parabola/mkgmap/osmstyle/ExpressionRule.java	(revision 3354)
+++ src/uk/me/parabola/mkgmap/osmstyle/ExpressionRule.java	(working copy)
@@ -16,6 +16,7 @@
  */
 package uk.me.parabola.mkgmap.osmstyle;
 
+import uk.me.parabola.log.Logger;
 import uk.me.parabola.mkgmap.osmstyle.eval.Op;
 import uk.me.parabola.mkgmap.reader.osm.Element;
 import uk.me.parabola.mkgmap.reader.osm.GType;
@@ -29,9 +30,13 @@
  * @author Steve Ratcliffe
  */
 public class ExpressionRule implements Rule {
+	private static final Logger statsLog = Logger.getLogger(ExpressionRule.class.getPackage().getName()+".stats");
+
 	private Op expression;
 	private final GType gtype;
 	private Rule finalizeRule;
+	private long numEval; // count how often the expression was evaluated 
+	private long numTrue; // count how often the evaluation returned true
 
 	/** Finalize rules must not have an element type definition so the add method must never be called. */
 	private final static TypeResult finalizeTypeResult = new TypeResult() {
@@ -47,7 +52,9 @@
 
 	
 	public void resolveType(Element el, TypeResult result) {
+		numEval++;
 		if (expression.eval(el)) {
+			numTrue++;
 			// expression matches
 			if (finalizeRule != null) {
 				if (gtype.isContinueSearch()) {
@@ -63,7 +70,9 @@
 	}
 
 	public int resolveType(int cacheId, Element el, TypeResult result) {
+		numEval++;
 		if (expression.eval(cacheId, el)){
+			numTrue++;
 			if (finalizeRule != null) {
 				if (gtype.isContinueSearch()) {
 					el = el.copy();
@@ -93,5 +102,10 @@
 	public void setOp(Op expression){
 		this.expression = expression;
 	}
-	
+
+	@Override
+	public void printStats(String header) {
+		if (statsLog.isInfoEnabled())
+			statsLog.info(header,"stats (rule/evals/true)", this.toString() + "/" + numEval + "/" + numTrue);
+	}
 }
Index: src/uk/me/parabola/mkgmap/osmstyle/RuleSet.java
===================================================================
--- src/uk/me/parabola/mkgmap/osmstyle/RuleSet.java	(revision 3354)
+++ src/uk/me/parabola/mkgmap/osmstyle/RuleSet.java	(working copy)
@@ -46,6 +46,7 @@
 public class RuleSet implements Rule, Iterable<Rule> {
 	private static final Logger log = Logger.getLogger(RuleSet.class);
 	private Rule[] rules;
+	private Rule finalizeRule;
 
 	// identifies cached values 
 	int cacheId;
@@ -259,5 +260,16 @@
 			rule.setFinalizeRule(finalizeRule);
 		
 		compiled = false;
+		this.finalizeRule = finalizeRule;  
 	}
+
+	@Override
+	public void printStats(String header) {
+		for (Rule rule : rules){ 
+			rule.printStats(header);
+		}
+		if (finalizeRule != null)
+			finalizeRule.printStats(header);
+	}
+
 } 
\ No newline at end of file
Index: src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
===================================================================
--- src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java	(revision 3354)
+++ src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java	(working copy)
@@ -124,6 +124,7 @@
 	private final Rule nodeRules;
 	private final Rule lineRules;
 	private final Rule polygonRules;
+	private Style style;
 
 	private boolean driveOnLeft;
 	private boolean driveOnRight;
@@ -153,7 +154,7 @@
 				nameTagList.add(TagDict.getInstance().xlate(n));
 		} else 
 			nameTagList = null;
-
+		this.style = style;
 		wayRules = style.getWayRules();
 		nodeRules = style.getNodeRules();
 		lineRules = style.getLineRules();
@@ -504,6 +505,7 @@
 	}
 	
 	public void end() {
+		style.reportStats();
 		setHighwayCounts();
 		findUnconnectedRoads();
 		rotateClosedWaysToFirstNode();
Index: src/uk/me/parabola/mkgmap/osmstyle/StyleImpl.java
===================================================================
--- src/uk/me/parabola/mkgmap/osmstyle/StyleImpl.java	(revision 3354)
+++ src/uk/me/parabola/mkgmap/osmstyle/StyleImpl.java	(working copy)
@@ -568,6 +568,14 @@
 		}
 		return style;
 	}
+
+	@Override
+	public void reportStats() {
+		relations.printStats("relations");
+		nodes.printStats("points");
+		lines.printStats("lines");
+		polygons.printStats("polygons");
+	}
 	
 	public static void main(String[] args) throws FileNotFoundException {
 		String file = args[0];
Index: src/uk/me/parabola/mkgmap/reader/osm/OsmMapDataSource.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/OsmMapDataSource.java	(revision 3354)
+++ src/uk/me/parabola/mkgmap/reader/osm/OsmMapDataSource.java	(working copy)
@@ -150,13 +150,13 @@
 	 */
 	protected void setupHandler(OsmHandler handler) {
 		createElementSaver();
+		createConverter();
+		
 		osmReadingHooks = pluginChain(elementSaver, getConfig());
 
 		handler.setElementSaver(elementSaver);
 		handler.setHooks(osmReadingHooks);
 
-		createConverter();
-
 		handler.setUsedTags(getUsedTags());
 
 		String deleteTagsFileName = getConfig().getProperty("delete-tags-file");
@@ -180,10 +180,12 @@
 	
 	protected OsmReadingHooks pluginChain(ElementSaver saver, EnhancedProperties props) {
 		List<OsmReadingHooks> plugins = new ArrayList<OsmReadingHooks>();
-
 		for (OsmReadingHooks p : getPossibleHooks()) {
-			if (p.init(saver, props))
+			if (p.init(saver, props)){
 				plugins.add(p);
+				if (p instanceof RelationStyleHook)
+					((RelationStyleHook) p).setStyle(style);
+			}
 		}
 
 		OsmReadingHooks hooks;
Index: src/uk/me/parabola/mkgmap/reader/osm/RelationStyleHook.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/RelationStyleHook.java	(revision 3354)
+++ src/uk/me/parabola/mkgmap/reader/osm/RelationStyleHook.java	(working copy)
@@ -35,10 +35,13 @@
 	public boolean init(ElementSaver saver, EnhancedProperties props) {
 		this.saver = saver;
 		nameTagList = LocatorUtil.getNameTags(props);
-		style = StyleImpl.readStyle(props);
 		return super.init(saver, props);
 	}
 
+	public void setStyle(Style style){
+		this.style = style;
+	}
+	
 	public void end() {
 		Rule relationRules = style.getRelationRules();
 		for (Relation rel : saver.getRelations().values()) {
@@ -57,8 +60,6 @@
 			}
 		}
 		super.end();
-		
-		style = null;
 	}
 
 	
Index: src/uk/me/parabola/mkgmap/reader/osm/Rule.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/Rule.java	(revision 3354)
+++ src/uk/me/parabola/mkgmap/reader/osm/Rule.java	(working copy)
@@ -53,5 +53,6 @@
 	 */
 	public void setFinalizeRule(Rule finalizeRule);
 	
+	public void printStats(String header);
 	
 }
Index: src/uk/me/parabola/mkgmap/reader/osm/Style.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/Style.java	(revision 3354)
+++ src/uk/me/parabola/mkgmap/reader/osm/Style.java	(working copy)
@@ -74,4 +74,9 @@
 	 * Get the tags that are used by this style.
 	 */
 	public Set<String> getUsedTags();
+	
+	/**
+	 * Report statistics for rule expressions. 
+	 */
+	public void reportStats();
 }
