Index: trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactoryTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactoryTest.java	(revision 17752)
+++ trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactoryTest.java	(revision 17758)
@@ -8,4 +8,7 @@
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import net.trajano.commons.testing.UtilityClassTestUtil;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
 
 /**
@@ -29,3 +32,17 @@
         UtilityClassTestUtil.assertUtilityClassWellDefined(Functions.class);
     }
+
+    /**
+     * Tests that all functions have been registered to {@link ExpressionFactory#FACTORY_MAP}
+     *
+     * For instance to register {@link Functions#osm_id}, {@code FACTORY_MAP.put("osm_id", Factory.ofEnv(Functions::osm_id))}
+     */
+    @Test
+    void testNoUnregisteredFunctions() {
+        for (Method m : Functions.class.getDeclaredMethods()) {
+            if (!Modifier.isPrivate(m.getModifiers()) && !ExpressionFactory.FACTORY_MAP.containsKey(m.getName())) {
+                throw new AssertionError(m + " has not registered in ExpressionFactory.FACTORY_MAP");
+            }
+        }
+    }
 }
Index: trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParserTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParserTest.java	(revision 17752)
+++ trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParserTest.java	(revision 17758)
@@ -368,11 +368,11 @@
         MultiCascade mc = new MultiCascade();
         sheet.apply(mc, OsmUtils.createPrimitive("way foo=bar"), 20, false);
-        assertEquals(Float.valueOf(5f), mc.getCascade(null).get("width"));
+        assertEquals(5.0f, mc.getCascade(null).get("width"));
         sheet.apply(mc, OsmUtils.createPrimitive("way keyA=true"), 20, false);
-        assertEquals(Float.valueOf(15f), mc.getCascade(null).get("width"));
+        assertEquals(15.0, mc.getCascade(null).get("width"));
         sheet.apply(mc, OsmUtils.createPrimitive("way keyB=true"), 20, false);
-        assertEquals(Float.valueOf(15f), mc.getCascade(null).get("width"));
+        assertEquals(15.0, mc.getCascade(null).get("width"));
         sheet.apply(mc, OsmUtils.createPrimitive("way keyA=true keyB=true"), 20, false);
-        assertEquals(Float.valueOf(15f), mc.getCascade(null).get("width"));
+        assertEquals(15.0, mc.getCascade(null).get("width"));
     }
 
@@ -480,5 +480,5 @@
     @Test
     void testSort() throws Exception {
-        assertEquals(Arrays.asList(new String[] {"alpha", "beta"}), Functions.sort("beta", "alpha"));
+        assertEquals(Arrays.asList(new String[] {"alpha", "beta"}), Functions.sort(null, "beta", "alpha"));
         Way way1 = TestUtils.newWay("highway=residential name=Alpha alt_name=Beta ref=\"A9;A8\"", new Node(new LatLon(0.001, 0.001)),
                 new Node(new LatLon(0.002, 0.002)));
@@ -490,5 +490,5 @@
         assertTrue(source.rules.get(0).matches(e));
         source.rules.get(0).declaration.execute(e);
-        assertEquals(Functions.join(",", "Alpha", "Beta"), e.getCascade(null).get("sorted", null, String.class));
+        assertEquals(Functions.join(null, ",", "Alpha", "Beta"), e.getCascade(null).get("sorted", null, String.class));
 
         source = new MapCSSStyleSource("way[ref] {sorted: join_list(\",\", sort_list(split(\";\", tag(\"ref\"))));}");
@@ -497,5 +497,5 @@
         assertTrue(source.rules.get(0).matches(e));
         source.rules.get(0).declaration.execute(e);
-        assertEquals(Functions.join(",", "A8", "A9"), e.getCascade(null).get("sorted", null, String.class));
+        assertEquals(Functions.join(null, ",", "A8", "A9"), e.getCascade(null).get("sorted", null, String.class));
     }
 
@@ -503,5 +503,5 @@
     void testUniqueValues() throws Exception {
         assertEquals(Arrays.asList(new String[] {"alpha", "beta"}),
-                Functions.uniq("alpha", "alpha", "alpha", "beta"));
+                Functions.uniq(null, "alpha", "alpha", "alpha", "beta"));
         assertEquals(Arrays.asList(new String[] {"one", "two", "three"}),
                 Functions.uniq_list(Arrays.asList(new String[] {"one", "one", "two", "two", "two", "three"})));
@@ -597,4 +597,16 @@
 
     @Test
+    void testMath() {
+        MapCSSStyleSource source = new MapCSSStyleSource("node { add: 1 + 2 + 3 + 4; mul: 2 * 3 * 5 * 7; sub: 0 - 1 - 2 - 3; div: 360 / 15; }");
+        source.loadStyleSource();
+        MultiCascade mc = new MultiCascade();
+        source.apply(mc, OsmUtils.createPrimitive("node"), 20, false);
+        assertEquals(10.0, mc.getCascade(null).get("add"));
+        assertEquals(210.0, mc.getCascade(null).get("mul"));
+        assertEquals(-6.0, mc.getCascade(null).get("sub"));
+        assertEquals(24.0, mc.getCascade(null).get("div"));
+    }
+
+    @Test
     void testMinMaxFunctions() throws Exception {
         MapCSSStyleSource sheet = new MapCSSStyleSource("* {" +
