Index: trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java	(revision 6533)
+++ trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java	(revision 6534)
@@ -29,5 +29,5 @@
 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.Expression;
 import org.openstreetmap.josm.gui.mappaint.mapcss.Instruction;
 import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSRule;
@@ -57,5 +57,5 @@
     static class TagCheck implements Predicate<OsmPrimitive> {
         protected final List<Selector> selector;
-        protected final List<Tag> change = new ArrayList<Tag>();
+        protected final List<PrimitiveToTag> change = new ArrayList<PrimitiveToTag>();
         protected final Map<String, String> keyChange = new LinkedHashMap<String, String>();
         protected final List<Tag> alternatives = new ArrayList<Tag>();
@@ -65,4 +65,37 @@
         TagCheck(List<Selector> selector) {
             this.selector = selector;
+        }
+
+        /**
+         * A function mapping the matched {@link OsmPrimitive} to a {@link Tag}.
+         */
+        static abstract class PrimitiveToTag implements Utils.Function<OsmPrimitive, Tag> {
+
+            /**
+             * Creates a new mapping from an {@code MapCSS} object.
+             * In case of an {@link Expression}, that is evaluated on the matched {@link OsmPrimitive}.
+             * In case of a {@link String}, that is "compiled" to a {@link Tag} instance.
+             */
+            static PrimitiveToTag ofMapCSSObject(final Object obj, final boolean keyOnly) {
+                if (obj instanceof Expression) {
+                    return new PrimitiveToTag() {
+                        @Override
+                        public Tag apply(OsmPrimitive p) {
+                            final String s = (String) ((Expression) obj).evaluate(new Environment().withPrimitive(p));
+                            return keyOnly? new Tag(s) : Tag.ofString(s);
+                        }
+                    };
+                } else if (obj instanceof String) {
+                    final Tag tag = keyOnly ? new Tag((String) obj) : Tag.ofString((String) obj);
+                    return new PrimitiveToTag() {
+                        @Override
+                        public Tag apply(OsmPrimitive ignore) {
+                            return tag;
+                        }
+                    };
+                } else {
+                    return null;
+                }
+            }
         }
 
@@ -72,6 +105,6 @@
                 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())
+                    final String val = ai.val instanceof Expression
+                            ? (String) ((Expression) ai.val).evaluate(new Environment())
                             : ai.val instanceof String
                             ? (String) ai.val
@@ -80,9 +113,11 @@
                         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 ("fixAdd".equals(ai.key)) {
+                        final PrimitiveToTag toTag = PrimitiveToTag.ofMapCSSObject(ai.val, false);
+                        check.change.add(toTag);
+                    } else if ("fixRemove".equals(ai.key)) {
+                        CheckParameterUtil.ensureThat(!(ai.val instanceof String) || !val.contains("="), "Unexpected '='. Please only specify the key to remove!");
+                        final PrimitiveToTag toTag = PrimitiveToTag.ofMapCSSObject(ai.val, true);
+                        check.change.add(toTag);
                     } else if ("fixChangeKey".equals(ai.key) && val != null) {
                         CheckParameterUtil.ensureThat(val.contains("=>"), "Separate old from new key by '=>'!");
@@ -159,5 +194,6 @@
             }
             Collection<Command> cmds = new LinkedList<Command>();
-            for (Tag tag : change) {
+            for (PrimitiveToTag toTag : change) {
+                final Tag tag = toTag.apply(p);
                 cmds.add(new ChangePropertyCommand(p, tag.getKey(), tag.getValue()));
             }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/Cascade.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/Cascade.java	(revision 6533)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/Cascade.java	(revision 6534)
@@ -115,10 +115,6 @@
 
     private static Float toFloat(Object o) {
-        if (o instanceof Float)
-            return (Float) o;
-        if (o instanceof Double)
-            return new Float((Double) o);
-        if (o instanceof Integer)
-            return new Float((Integer) o);
+        if (o instanceof Number)
+            return ((Number) o).floatValue();
         if (o instanceof String && !((String) o).isEmpty()) {
             try {
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java	(revision 6533)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java	(revision 6534)
@@ -131,20 +131,37 @@
         }
 
+        /**
+         * Creates a list of values, e.g., for the {@code dashes} property.
+         * @see {@link Arrays#asList(Object[])}
+         */
         public static List list(Object... args) {
             return Arrays.asList(args);
         }
 
-        public static Object get(List<? extends Object> objects, float index) {
-            int idx = Math.round(index);
-            if (idx >= 0 && idx < objects.size()) {
-                return objects.get(idx);
+        /**
+         * Get the {@code n}th element of the list {@code lst} (counting starts at 0).
+         * @since 5699
+         */
+        public static Object get(List<?> lst, float n) {
+            int idx = Math.round(n);
+            if (idx >= 0 && idx < lst.size()) {
+                return lst.get(idx);
             }
             return null;
         }
 
+        /**
+         * Splits string {@code toSplit} at occurrences of the separator string {@code sep} and returns a list of matches.
+         * @see {@link String#split(String)}
+         * @since 5699
+         */
         public static List<String> split(String sep, String toSplit) {
             return Arrays.asList(toSplit.split(Pattern.quote(sep), -1));
         }
 
+        /**
+         * Creates a color value with the specified amounts of {@code r}ed, {@code g}reen, {@code b}lue (arguments from 0.0 to 1.0)
+         * @see {@link Color#Color(float, float, float)}
+         */
         public static Color rgb(float r, float g, float b) {
             Color c;
@@ -157,24 +174,45 @@
         }
 
+        /**
+         * Creates a color value from an HTML notation, i.e., {@code #rrggbb}.
+         */
         public static Color html2color(String html) {
             return ColorHelper.html2color(html);
         }
 
+        /**
+         * Computes the HTML notation ({@code #rrggbb}) for a color value).
+         */
         public static String color2html(Color c) {
             return ColorHelper.color2html(c);
         }
 
+        /**
+         * Get the value of the red color channel in the rgb color model
+         * @see {@link java.awt.Color#getRed()}
+         */
         public static float red(Color c) {
             return Utils.color_int2float(c.getRed());
         }
 
+        /**
+         * Get the value of the green color channel in the rgb color model
+         * @see {@link java.awt.Color#getGreen()}
+         */
         public static float green(Color c) {
             return Utils.color_int2float(c.getGreen());
         }
 
+        /**
+         * Get the value of the blue color channel in the rgb color model
+         * @see {@link java.awt.Color#getBlue()}
+         */
         public static float blue(Color c) {
             return Utils.color_int2float(c.getBlue());
         }
 
+        /**
+         * Assembles the strings to one.
+         */
         public static String concat(Object... args) {
             StringBuilder res = new StringBuilder();
@@ -185,8 +223,14 @@
         }
 
+        /**
+         * Returns the value of the property {@code key}, e.g., {@code prop("width")}.
+         */
         public Object prop(String key) {
             return prop(key, null);
         }
 
+        /**
+         * Returns the value of the property {@code key} from layer {@code layer}.
+         */
         public Object prop(String key, String layer) {
             Cascade c;
@@ -199,8 +243,14 @@
         }
 
+        /**
+         * Determines whether property {@code key} is set.
+         */
         public Boolean is_prop_set(String key) {
             return is_prop_set(key, null);
         }
 
+        /**
+         * Determines whether property {@code key} is set on layer {@code layer}.
+         */
         public Boolean is_prop_set(String key, String layer) {
             Cascade c;
@@ -216,8 +266,14 @@
         }
 
+        /**
+         * Gets the value of the key {@code key} from the object in question.
+         */
         public String tag(String key) {
             return env.osm.get(key);
         }
 
+        /**
+         * Gets the first non-null value of the key {@code key} from the object's parent(s).
+         */
         public String parent_tag(String key) {
             if (env.parent == null) {
@@ -234,8 +290,14 @@
         }
 
+        /**
+         * Determines whether the object has a tag with the given key.
+         */
         public boolean has_tag_key(String key) {
             return env.osm.hasKey(key);
         }
 
+        /**
+         * Returns the index of node in parent way or member in parent relation.
+         */
         public Float index() {
             if (env.index == null) {
@@ -269,4 +331,8 @@
         }
 
+        /**
+         * Determines if the objects {@code a} and {@code b} are equal.
+         * @see {@link Object#equals(Object)}
+         */
         public static boolean equal(Object a, Object b) {
             // make sure the casts are done in a meaningful way, so
@@ -282,8 +348,11 @@
         }
 
-        public Boolean JOSM_search(String s) {
+        /**
+         * Determines whether the JOSM search with {@code searchStr} applies to the object.
+         */
+        public Boolean JOSM_search(String searchStr) {
             Match m;
             try {
-                m = SearchCompiler.compile(s, false, false);
+                m = SearchCompiler.compile(searchStr, false, false);
             } catch (ParseError ex) {
                 return null;
@@ -292,18 +361,38 @@
         }
 
-        public static String JOSM_pref(String s, String def) {
-            String res = Main.pref.get(s, null);
+        /**
+         * Obtains the JOSM'key {@link org.openstreetmap.josm.data.Preferences} string for key {@code key},
+         * and defaults to {@code def} if that is null.
+         * @see {@link org.openstreetmap.josm.data.Preferences#get(String, String)}
+         */
+        public static String JOSM_pref(String key, String def) {
+            String res = Main.pref.get(key, null);
             return res != null ? res : def;
         }
 
-        public static Color JOSM_pref_color(String s, Color def) {
-            Color res = Main.pref.getColor(s, null);
+        /**
+         * Obtains the JOSM'key {@link org.openstreetmap.josm.data.Preferences} color for key {@code key},
+         * and defaults to {@code def} if that is null.
+         * @see {@link org.openstreetmap.josm.data.Preferences#getColor(String, java.awt.Color)}
+         */
+        public static Color JOSM_pref_color(String key, Color def) {
+            Color res = Main.pref.getColor(key, null);
             return res != null ? res : def;
         }
 
+        /**
+         * Tests if string {@code target} matches pattern {@code pattern}
+         * @see {@link Pattern#matches(String, CharSequence)}
+         * @since 5699
+         */
         public static boolean regexp_test(String pattern, String target) {
             return Pattern.matches(pattern, target);
         }
 
+        /**
+         * Tests if string {@code target} matches pattern {@code pattern}
+         * @param flags a string that may contain "i" (case insensitive), "m" (multiline) and "s" ("dot all")
+         * @since 5699
+         */
         public static boolean regexp_test(String pattern, String target, String flags) {
             int f = 0;
@@ -320,4 +409,11 @@
         }
 
+        /**
+         * Tries to match string against pattern regexp and returns a list of capture groups in case of success.
+         * The first element (index 0) is the complete match (i.e. string).
+         * Further elements correspond to the bracketed parts of the regular expression.
+         * @param flags a string that may contain "i" (case insensitive), "m" (multiline) and "s" ("dot all")
+         * @since 5701
+         */
         public static List<String> regexp_match(String pattern, String target, String flags) {
             int f = 0;
@@ -343,4 +439,10 @@
         }
 
+        /**
+         * Tries to match string against pattern regexp and returns a list of capture groups in case of success.
+         * The first element (index 0) is the complete match (i.e. string).
+         * Further elements correspond to the bracketed parts of the regular expression.
+         * @since 5701
+         */
         public static List<String> regexp_match(String pattern, String target) {
             Matcher m = Pattern.compile(pattern).matcher(target);
@@ -356,12 +458,45 @@
         }
 
+        /**
+         * Returns the OSM id of the current object.
+         * @see {@link org.openstreetmap.josm.data.osm.AbstractPrimitive#generateUniqueId()}
+         */
         public long osm_id() {
             return env.osm.getUniqueId();
         }
 
+        /**
+         * Translates some text for the current locale. The first argument is the text to translate,
+         * and the subsequent arguments are parameters for the string indicated by {@code {0}}, {@code {1}}, …
+         */
         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);
+        }
+
+        /**
+         * Returns the substring of {@code s} starting at index {@code begin} (inclusive, 0-indexed).
+         * * @see {@link String#substring(int)}
+         */
+        public static String substring(String s, /* due to missing Cascade.convertTo for int*/ float begin) {
+            return s == null ? null : s.substring((int) begin);
+        }
+
+        /**
+         * Returns the substring of {@code s} starting at index {@code begin} (inclusive)
+         * and ending at index {@code end}, (exclusive, 0-indexed).
+         * @see {@link String#substring(int, int)}
+         */
+        public static String substring(String s, float begin, float end) {
+            return s == null ? null : s.substring((int) begin, (int) end);
+        }
+
+        /**
+         * Replaces in {@code s} every {@code} target} substring by {@code replacement}.
+         * * @see {@link String#replace(CharSequence, CharSequence)}
+         */
+        public static String replace(String s, String target, String replacement) {
+            return s == null ? null : s.replace(target, replacement);
         }
     }
