Index: /trunk/src/org/openstreetmap/josm/data/validation/tests/RelationChecker.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/validation/tests/RelationChecker.java	(revision 7253)
+++ /trunk/src/org/openstreetmap/josm/data/validation/tests/RelationChecker.java	(revision 7254)
@@ -70,7 +70,10 @@
     /**
      * Reads the presets data.
-     *
      */
-    public void initializePresets() {
+    public static synchronized void initializePresets() {
+        if (!relationpresets.isEmpty()) {
+            // the presets have already been initialized
+            return;
+        }
         for (TaggingPreset p : TaggingPresets.getTaggingPresets()) {
             for (TaggingPresetItem i : p.data) {
Index: /trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPresetItems.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPresetItems.java	(revision 7253)
+++ /trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPresetItems.java	(revision 7254)
@@ -170,5 +170,5 @@
 
         public boolean required = false;
-        public long count = 0;
+        private long count = 0;
 
         public void setType(String types) throws SAXException {
@@ -191,17 +191,22 @@
         }
 
-        /* return either argument, the highest possible value or the lowest
-           allowed value */
-        public long getValidCount(long c)
-        {
-            if(count > 0 && !required)
+        public void setCount(String count) {
+            this.count = Long.parseLong(count);
+        }
+
+        /**
+         * Return either argument, the highest possible value or the lowest allowed value
+         */
+        public long getValidCount(long c) {
+            if (count > 0 && !required)
                 return c != 0 ? count : 0;
-            else if(count > 0)
+            else if (count > 0)
                 return count;
-            else if(!required)
-                return c != 0  ? c : 0;
+            else if (!required)
+                return c != 0 ? c : 0;
             else
-                return c != 0  ? c : 1;
-        }
+                return c != 0 ? c : 1;
+        }
+
         public boolean addToPanel(JPanel p, Collection<OsmPrimitive> sel) {
             String cstring;
Index: /trunk/test/unit/org/openstreetmap/josm/data/validation/tests/RelationCheckerTest.groovy
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/data/validation/tests/RelationCheckerTest.groovy	(revision 7254)
+++ /trunk/test/unit/org/openstreetmap/josm/data/validation/tests/RelationCheckerTest.groovy	(revision 7254)
@@ -0,0 +1,113 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.validation.tests
+
+import org.openstreetmap.josm.JOSMFixture
+import org.openstreetmap.josm.data.osm.Relation
+import org.openstreetmap.josm.data.osm.RelationMember
+import org.openstreetmap.josm.data.osm.Way
+import org.openstreetmap.josm.data.validation.TestError
+import org.openstreetmap.josm.gui.tagging.TaggingPresets
+
+import static org.openstreetmap.josm.TestUtils.createPrimitive
+
+class RelationCheckerTest extends GroovyTestCase {
+
+    @Override
+    void setUp() {
+        JOSMFixture.createUnitTestFixture().init();
+        getRelationChecker()
+    }
+
+    static def RelationChecker getRelationChecker() {
+        def checker = new RelationChecker()
+        TaggingPresets.readFromPreferences()
+        checker.initialize()
+        return checker
+    }
+
+    static def List<TestError> testRelation(Relation r) {
+        def checker = getRelationChecker()
+        checker.visit(r)
+        return checker.getErrors()
+    }
+
+    static def Relation createRelation(String tags) {
+        return (Relation) createPrimitive("relation "+ tags)
+    }
+
+    void testUnknownType() {
+        def errors = testRelation(createRelation("type=foobar"))
+        assert errors.size() == 1
+        assert errors.get(0).getMessage() == "Relation type is unknown"
+    }
+
+    void testEmpty() {
+        def errors = testRelation(createRelation("type=multipolygon"))
+        assert errors.size() == 1
+        assert errors.get(0).getMessage() == "Relation is empty"
+    }
+
+    void testOuter2() {
+        def r = createRelation("type=multipolygon")
+        r.addMember(new RelationMember("outer", new Way()))
+        r.addMember(new RelationMember("outer2", new Way()))
+
+        def errors = testRelation(r)
+        assert errors.size() == 1
+        assert errors.get(0).getDescription() == "Role outer2 unknown"
+    }
+
+    void testRestrictionViaMissing() {
+        def r = createRelation("type=restriction")
+        r.addMember(new RelationMember("from", new Way()))
+        r.addMember(new RelationMember("to", new Way()))
+
+        def errors = testRelation(r)
+        assert errors.size() == 1
+        assert errors.get(0).getDescription() == "Role via missing"
+    }
+
+    void testRestrictionViaRelation() {
+        def r = createRelation("type=restriction")
+        r.addMember(new RelationMember("from", new Way()))
+        r.addMember(new RelationMember("to", new Way()))
+        r.addMember(new RelationMember("via", new Relation()))
+
+        def errors = testRelation(r)
+        assert errors.size() == 1
+        assert errors.get(0).getDescription() == "Member for role via of wrong type"
+    }
+
+    void testRestrictionTwoFrom() {
+        def r = createRelation("type=restriction")
+        r.addMember(new RelationMember("from", new Way()))
+        r.addMember(new RelationMember("from", new Way()))
+        r.addMember(new RelationMember("to", new Way()))
+        r.addMember(new RelationMember("via", new Way()))
+
+        def errors = testRelation(r)
+        assert errors.size() == 1
+        assert errors.get(0).getDescription() == "Number of from roles too high (2)"
+    }
+
+    void testRestrictionEmpty() {
+        def r = createRelation("type=restriction")
+        r.addMember(new RelationMember("from", new Way()))
+        r.addMember(new RelationMember("to", new Way()))
+        r.addMember(new RelationMember("via", new Way()))
+        r.addMember(new RelationMember("", new Way()))
+
+        def errors = testRelation(r)
+        assert errors.size() == 1
+        assert errors.get(0).getDescription() == "Empty role found"
+    }
+
+    void testPowerMemberExpression() {
+        def r = createRelation("type=route route=power")
+        r.addMember(new RelationMember("", new Way()))
+
+        def errors = testRelation(r)
+        assert errors.size() == 1
+        assert errors.get(0).getDescription() == "Member for role '<empty>' does not match 'power'"
+    }
+}
