Index: /trunk/data/validator/geometry.mapcss
===================================================================
--- /trunk/data/validator/geometry.mapcss	(revision 10709)
+++ /trunk/data/validator/geometry.mapcss	(revision 10710)
@@ -152,16 +152,21 @@
 node[tag("amenity") = parent_tag("amenity")] ∈ *[amenity][amenity != parking] {
   throwWarning: tr("{0} inside {1}", concat("amenity=", tag("amenity")), concat("amenity=", tag("amenity")));
+  group: tr("{0} inside {1}", "amenity", "amenity");
 }
 node[tag("leisure") = parent_tag("leisure")] ∈ *[leisure] {
   throwWarning: tr("{0} inside {1}", concat("leisure=", tag("leisure")), concat("leisure=", tag("leisure")));
+  group: tr("{0} inside {1}", "leisure", "leisure");
 }
 node[tag("tourism") = parent_tag("tourism")] ∈ *[tourism] {
   throwWarning: tr("{0} inside {1}", concat("tourism=", tag("tourism")), concat("tourism=", tag("tourism")));
+  group: tr("{0} inside {1}", "tourism", "tourism");
 }
 node[tag("shop") = parent_tag("shop")] ∈ *[shop] {
   throwWarning: tr("{0} inside {1}", concat("shop=", tag("shop")), concat("shop=", tag("shop")));
+  group: tr("{0} inside {1}", "shop", "shop");
 }
 node[tag("power") = parent_tag("power")] ∈ *[power] {
   throwWarning: tr("{0} inside {1}", concat("power=", tag("power")), concat("power=", tag("power")));
+  group: tr("{0} inside {1}", "power", "power");
 }
 
Index: /trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java	(revision 10709)
+++ /trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java	(revision 10710)
@@ -255,11 +255,21 @@
 
     public static class TagCheck implements Predicate<OsmPrimitive> {
+        /** The selector of this {@code TagCheck} */
         protected final GroupedMapCSSRule rule;
+        /** Commands to apply in order to fix a matching primitive */
         protected final List<FixCommand> fixCommands = new ArrayList<>();
+        /** Tags (or arbitraty strings) of alternatives to be presented to the user */
         protected final List<String> alternatives = new ArrayList<>();
+        /** An {@link Instruction.AssignmentInstruction}-{@link Severity} pair.
+         * Is evaluated on the matching primitive to give the error message. Map is checked to contain exactly one element. */
         protected final Map<Instruction.AssignmentInstruction, Severity> errors = new HashMap<>();
+        /** Unit tests */
         protected final Map<String, Boolean> assertions = new HashMap<>();
+        /** MapCSS Classes to set on matching primitives */
         protected final Set<String> setClassExpressions = new HashSet<>();
+        /** Denotes whether the object should be deleted for fixing it */
         protected boolean deletion;
+        /** A string used to group similar tests */
+        protected String group;
 
         TagCheck(GroupedMapCSSRule rule) {
@@ -324,4 +334,6 @@
                     } else if ("assertNoMatch".equals(ai.key) && val != null) {
                         check.assertions.put(val, Boolean.FALSE);
+                    } else if ("group".equals(ai.key) && val != null) {
+                        check.group = val;
                     } else {
                         throw new IllegalDataException("Cannot add instruction " + ai.key + ": " + ai.val + '!');
@@ -563,4 +575,6 @@
                 final Command fix = fixPrimitive(p);
                 final String description = getDescriptionForMatchingSelector(p, matchingSelector);
+                final String description1 = group == null ? description : group;
+                final String description2 = group == null ? null : description;
                 final List<OsmPrimitive> primitives;
                 if (env.child != null) {
@@ -570,7 +584,7 @@
                 }
                 if (fix != null) {
-                    return new FixableTestError(null, getSeverity(), description, null, matchingSelector.toString(), 3000, primitives, fix);
+                    return new FixableTestError(null, getSeverity(), description1, description2, matchingSelector.toString(), 3000, primitives, fix);
                 } else {
-                    return new TestError(null, getSeverity(), description, null, matchingSelector.toString(), 3000, primitives);
+                    return new TestError(null, getSeverity(), description1, description2, matchingSelector.toString(), 3000, primitives);
                 }
             } else {
Index: /trunk/test/unit/org/openstreetmap/josm/data/validation/tests/MapCSSTagCheckerTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/data/validation/tests/MapCSSTagCheckerTest.java	(revision 10709)
+++ /trunk/test/unit/org/openstreetmap/josm/data/validation/tests/MapCSSTagCheckerTest.java	(revision 10710)
@@ -55,4 +55,5 @@
         ParseResult result = MapCSSTagChecker.TagCheck.readMapCSS(new StringReader("" +
                 "*[natural=marsh] {\n" +
+                "   group: tr(\"deprecated\");\n" +
                 "   throwWarning: tr(\"{0}={1} is deprecated\", \"{0.key}\", tag(\"natural\"));\n" +
                 "   fixRemove: \"{0.key}\";\n" +
@@ -72,5 +73,6 @@
         n1.put("natural", "marsh");
         assertTrue(check.test(n1));
-        assertEquals("natural=marsh is deprecated", check.getErrorForPrimitive(n1).getMessage());
+        assertEquals("deprecated", check.getErrorForPrimitive(n1).getMessage());
+        assertEquals("natural=marsh is deprecated", check.getErrorForPrimitive(n1).getDescription());
         assertEquals(Severity.WARNING, check.getErrorForPrimitive(n1).getSeverity());
         assertEquals("Sequence: Fix of natural=marsh is deprecated", check.fixPrimitive(n1).getDescriptionText());
