Index: trunk/src/org/openstreetmap/josm/data/osm/Tag.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/Tag.java	(revision 6501)
+++ trunk/src/org/openstreetmap/josm/data/osm/Tag.java	(revision 6506)
@@ -1,4 +1,6 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.data.osm;
+
+import org.openstreetmap.josm.tools.CheckParameterUtil;
 
 /**
@@ -97,4 +99,14 @@
     }
 
+    public static Tag ofString(String s) {
+        CheckParameterUtil.ensureParameterNotNull(s, "s");
+        final String[] x = s.split("=", 2);
+        if (x.length == 2) {
+            return new Tag(x[0], x[1]);
+        } else {
+            throw new IllegalArgumentException("String does not contain '='");
+        }
+    }
+
     @Override
     public String toString() {
Index: trunk/src/org/openstreetmap/josm/data/validation/OsmValidator.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/OsmValidator.java	(revision 6501)
+++ trunk/src/org/openstreetmap/josm/data/validation/OsmValidator.java	(revision 6506)
@@ -35,4 +35,5 @@
 import org.openstreetmap.josm.data.validation.tests.DuplicatedWayNodes;
 import org.openstreetmap.josm.data.validation.tests.Highways;
+import org.openstreetmap.josm.data.validation.tests.MapCSSTagChecker;
 import org.openstreetmap.josm.data.validation.tests.MultipolygonTest;
 import org.openstreetmap.josm.data.validation.tests.NameMismatch;
@@ -106,5 +107,5 @@
         DuplicateRelation.class, // ID 1901 .. 1999
         BuildingInBuilding.class, // ID 2001 .. 2099
-        DeprecatedTags.class, // ID 2101 .. 2199
+        //DeprecatedTags.class, // ID 2101 .. 2199
         OverlappingAreas.class, // ID 2201 .. 2299
         WayConnectedToArea.class, // ID 2301 .. 2399
@@ -114,5 +115,6 @@
         Highways.class, // ID 2701 .. 2799
         BarriersEntrances.class, // ID 2801 .. 2899
-        OpeningHourTest.class // 2901 .. 2999
+        OpeningHourTest.class, // 2901 .. 2999
+        MapCSSTagChecker.class, // 3000 .. 3099
     };
     
Index: trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java	(revision 6506)
+++ trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java	(revision 6506)
@@ -0,0 +1,213 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.validation.tests;
+
+import org.openstreetmap.josm.command.ChangePropertyCommand;
+import org.openstreetmap.josm.command.ChangePropertyKeyCommand;
+import org.openstreetmap.josm.command.Command;
+import org.openstreetmap.josm.command.SequenceCommand;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.Tag;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.validation.FixableTestError;
+import org.openstreetmap.josm.data.validation.Severity;
+import org.openstreetmap.josm.data.validation.Test;
+import org.openstreetmap.josm.data.validation.TestError;
+import org.openstreetmap.josm.gui.mappaint.Environment;
+import org.openstreetmap.josm.gui.mappaint.mapcss.ExpressionFactory;
+import org.openstreetmap.josm.gui.mappaint.mapcss.Instruction;
+import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSRule;
+import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource;
+import org.openstreetmap.josm.gui.mappaint.mapcss.Selector;
+import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.MapCSSParser;
+import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.ParseException;
+import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Predicate;
+import org.openstreetmap.josm.tools.Utils;
+
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+public class MapCSSTagChecker extends Test {
+
+    public MapCSSTagChecker() {
+        super(tr("Tag checker (new)"), tr("This test checks for errors in tag keys and values."));
+    }
+
+    final List<TagCheck> checks = new ArrayList<TagCheck>();
+
+    static class TagCheck implements Predicate<OsmPrimitive> {
+        protected final List<Selector> selector;
+        protected final List<Tag> change = new ArrayList<Tag>();
+        protected final Map<String, String> keyChange = new LinkedHashMap<String, String>();
+        protected final List<Tag> alternatives = new ArrayList<Tag>();
+        protected final Map<String, Severity> errors = new HashMap<String, Severity>();
+
+        TagCheck(List<Selector> selector) {
+            this.selector = selector;
+        }
+
+        static TagCheck ofMapCSSRule(final MapCSSRule rule) {
+            final TagCheck check = new TagCheck(rule.selectors);
+            for (Instruction i : rule.declaration) {
+                if (i instanceof Instruction.AssignmentInstruction) {
+                    final Instruction.AssignmentInstruction ai = (Instruction.AssignmentInstruction) i;
+                    final String val = ai.val instanceof ExpressionFactory.ArrayFunction
+                            ? (String) ((ExpressionFactory.ArrayFunction) ai.val).evaluate(new Environment())
+                            : ai.val instanceof String
+                            ? (String) ai.val
+                            : null;
+                    if (ai.key.startsWith("throw")) {
+                        final Severity severity = Severity.valueOf(ai.key.substring("throw".length()).toUpperCase());
+                        check.errors.put(val, severity);
+                    } else if ("fixAdd".equals(ai.key) && val != null) {
+                        check.change.add(Tag.ofString(val));
+                    } else if ("fixRemove".equals(ai.key) && val != null) {
+                        CheckParameterUtil.ensureThat(!val.contains("="), "Unexpected '='. Please only specify the key to remove!");
+                        check.change.add(new Tag(val));
+                    } else if ("fixChangeKey".equals(ai.key) && val != null) {
+                        CheckParameterUtil.ensureThat(val.contains("=>"), "Separate old from new key by '=>'!");
+                        final String[] x = val.split("=>", 2);
+                        check.keyChange.put(x[0].trim(), x[1].trim());
+                    } else if ("suggestAlternative".equals(ai.key) && val != null) {
+                        check.alternatives.add(val.contains("=") ? Tag.ofString(val) : new Tag(val));
+                    } else {
+                        throw new RuntimeException("Cannot add instruction " + ai.key + ": " + ai.val + "!");
+                    }
+                }
+            }
+            if (check.errors.isEmpty()) {
+                throw new RuntimeException("No throwError/throwWarning/throwOther given! You should specify a validation error message for " + rule.selectors);
+            } else if (check.errors.size() > 1) {
+                throw new RuntimeException("More than one throwError/throwWarning/throwOther given! You should specify a single validation error message for " + rule.selectors);
+            }
+            return check;
+        }
+
+        static List<TagCheck> readMapCSS(Reader css) throws ParseException {
+            CheckParameterUtil.ensureParameterNotNull(css, "css");
+            return readMapCSS(new MapCSSParser(css));
+        }
+
+        static List<TagCheck> readMapCSS(MapCSSParser css) throws ParseException {
+            CheckParameterUtil.ensureParameterNotNull(css, "css");
+            final MapCSSStyleSource source = new MapCSSStyleSource("");
+            css.sheet(source);
+            assert source.getErrors().isEmpty();
+            return new ArrayList<TagCheck>(Utils.transform(source.rules, new Utils.Function<MapCSSRule, TagCheck>() {
+                @Override
+                public TagCheck apply(MapCSSRule x) {
+                    return TagCheck.ofMapCSSRule(x);
+                }
+            }));
+        }
+
+        @Override
+        public boolean evaluate(OsmPrimitive primitive) {
+            return matchesPrimitive(primitive);
+        }
+
+        /**
+         * Tests whether the {@link OsmPrimitive} contains a deprecated tag which is represented by this {@code MapCSSTagChecker}.
+         *
+         * @param primitive the primitive to test
+         * @return true when the primitive contains a deprecated tag
+         */
+        boolean matchesPrimitive(OsmPrimitive primitive) {
+            final Environment env = new Environment().withPrimitive(primitive);
+            for (Selector i : selector) {
+                if (i.matches(env)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        /**
+         * Constructs a fix in terms of a {@link org.openstreetmap.josm.command.Command} for the {@link OsmPrimitive}
+         * if the error is fixable, or {@code null} otherwise.
+         *
+         * @param p the primitive to construct the fix for
+         * @return the fix or {@code null}
+         */
+        Command fixPrimitive(OsmPrimitive p) {
+            if (change.isEmpty() && keyChange.isEmpty()) {
+                return null;
+            }
+            Collection<Command> cmds = new LinkedList<Command>();
+            for (Tag tag : change) {
+                cmds.add(new ChangePropertyCommand(p, tag.getKey(), tag.getValue()));
+            }
+            for (Map.Entry<String, String> i : keyChange.entrySet()) {
+                cmds.add(new ChangePropertyKeyCommand(p, i.getKey(), i.getValue()));
+            }
+            return new SequenceCommand(tr("Fix of {0}", getDescription()), cmds);
+        }
+
+        /**
+         * Constructs a (localized) description for this deprecation check.
+         *
+         * @return a description
+         */
+        String getDescription() {
+            return errors.keySet().iterator().next();
+        }
+
+        Severity getSeverity() {
+            return errors.values().iterator().next();
+        }
+
+    }
+
+    /**
+     * Visiting call for primitives.
+     *
+     * @param p The primitive to inspect.
+     */
+    public void visit(OsmPrimitive p) {
+        for (TagCheck check : checks) {
+            if (check.matchesPrimitive(p)) {
+                final Command fix = check.fixPrimitive(p);
+                if (fix != null) {
+                    errors.add(new FixableTestError(this, check.getSeverity(), check.getDescription(), 3000, p, fix));
+                } else {
+                    errors.add(new TestError(this, check.getSeverity(), check.getDescription(), 3000, p));
+                }
+            }
+        }
+    }
+
+    @Override
+    public void visit(Node n) {
+        visit((OsmPrimitive) n);
+    }
+
+    @Override
+    public void visit(Way w) {
+        visit((OsmPrimitive) w);
+    }
+
+    @Override
+    public void visit(Relation r) {
+        visit((OsmPrimitive) r);
+    }
+
+    public void addMapCSS(Reader css) throws ParseException {
+        checks.addAll(TagCheck.readMapCSS(css));
+    }
+
+    @Override
+    public void initialize() throws Exception {
+        addMapCSS(new InputStreamReader(getClass().getResourceAsStream("/data/validator/deprecated.mapcss"), "UTF-8"));
+    }
+}
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java	(revision 6501)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java	(revision 6506)
@@ -359,4 +359,10 @@
             return env.osm.getUniqueId();
         }
+
+        public static String tr(String... args) {
+            final String text = args[0];
+            System.arraycopy(args, 1, args, 0, args.length - 1);
+            return org.openstreetmap.josm.tools.I18n.tr(text, args);
+        }
     }
 
Index: trunk/src/org/openstreetmap/josm/tools/CheckParameterUtil.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/CheckParameterUtil.java	(revision 6501)
+++ trunk/src/org/openstreetmap/josm/tools/CheckParameterUtil.java	(revision 6506)
@@ -92,4 +92,14 @@
 
     /**
+     * Ensures that the condition {@code condition} holds.
+     * @param condition The condition to check
+     * @throws IllegalArgumentException if the condition does not hold
+     */
+    public static void ensureThat(boolean condition, String message) throws IllegalArgumentException {
+        if (!condition)
+            throw new IllegalArgumentException(message);
+    }
+
+    /**
      * Ensures that <code>id</code> is non-null primitive id of type {@link OsmPrimitiveType#NODE}
      *
