Index: src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java
===================================================================
--- src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java	(revision 15262)
+++ src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java	(working copy)
@@ -338,24 +338,34 @@
         public Object evaluate(Environment env) {
             Object[] convertedArgs;
 
+            int start = 0;
+            int offset = 0;
             if (needsEnvironment) {
-                convertedArgs = new Object[args.size()+1];
+                start = 1;
+                offset = 1;
+                convertedArgs = new Object[args.size() + 1];
                 convertedArgs[0] = env;
-                for (int i = 1; i < convertedArgs.length; ++i) {
-                    convertedArgs[i] = Cascade.convertTo(args.get(i-1).evaluate(env), expectedParameterTypes[i]);
-                    if (convertedArgs[i] == null && !nullable) {
-                        return null;
-                    }
-                }
             } else {
                 convertedArgs = new Object[args.size()];
-                for (int i = 0; i < convertedArgs.length; ++i) {
-                    convertedArgs[i] = Cascade.convertTo(args.get(i).evaluate(env), expectedParameterTypes[i]);
-                    if (convertedArgs[i] == null && !nullable) {
-                        return null;
+            }
+
+            for (int i = start; i < convertedArgs.length; ++i) {
+                if (!expectedParameterTypes[i].isArray()) {
+                    convertedArgs[i] = Cascade.convertTo(args.get(i - offset).evaluate(env), expectedParameterTypes[i]);
+                } else {
+                    Class<?> clazz = expectedParameterTypes[i].getComponentType();
+                    Object[] varargs = (Object[]) Array.newInstance(clazz, args.size() - i + 1);
+                    for (int j = 0; j < args.size() - i + 1; ++j) {
+                        varargs[j] = Cascade.convertTo(args.get(j + i - 1).evaluate(env), clazz);
                     }
+                    convertedArgs[i] = expectedParameterTypes[i].cast(varargs);
+                    break;
                 }
+                if (convertedArgs[i] == null && !nullable) {
+                    return null;
+                }
             }
+
             Object result = null;
             try {
                 result = m.invoke(null, convertedArgs);
Index: src/org/openstreetmap/josm/gui/mappaint/mapcss/Functions.java
===================================================================
--- src/org/openstreetmap/josm/gui/mappaint/mapcss/Functions.java	(revision 15262)
+++ src/org/openstreetmap/josm/gui/mappaint/mapcss/Functions.java	(working copy)
@@ -494,6 +494,20 @@
     }
 
     /**
+     * Sort an array of strings
+     * @param sortables The array to sort
+     * @return The sorted array
+     * @since xxx
+     */
+    public static List<String> sort(String... sortables) {
+        Logging.setLogLevel(Logging.LEVEL_DEBUG);
+        Logging.debug("Sorting");
+        Arrays.parallelSort(sortables);
+        Logging.debug("{}", (Object[]) sortables);
+        return Arrays.asList(sortables);
+    }
+
+    /**
      * Returns the role of current object in parent relation, or role of child if current object is a relation.
      * @param env the environment
      * @return role of current object in parent relation, or role of child if current object is a relation
@@ -504,7 +518,7 @@
     }
 
     /**
-     * Returns true if role is in relation. Returns false if not a relation or it does not have the role.
+     * Returns the number of primitives in a relation with the specified roles.
      * @param env the environment
      * @param roles The roles to count in the relation
      * @return The number of relation members with the specified role
Index: test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParserTest.java
===================================================================
--- test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParserTest.java	(revision 15262)
+++ test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParserTest.java	(working copy)
@@ -9,6 +9,7 @@
 
 import java.awt.Color;
 import java.io.StringReader;
+import java.util.Arrays;
 import java.util.List;
 
 import org.junit.Rule;
@@ -407,6 +408,21 @@
     }
 
     @Test
+    public void testSort() throws Exception {
+        assertEquals(Arrays.asList(new String[] {"alpha", "beta"}), Functions.sort("beta", "alpha"));
+        Way way1 = TestUtils.newWay("highway=residential name=Alpha alt_name=Beta", new Node(new LatLon(0.001, 0.001)),
+                new Node(new LatLon(0.002, 0.002)));
+
+        MapCSSStyleSource source = new MapCSSStyleSource("way[highway] {sorted: join_list(\",\", sort(tag(\"alt_name\"), tag(\"name\")));}");
+        source.loadStyleSource();
+        assertEquals(1, source.rules.size());
+        Environment e = new Environment(way1, new MultiCascade(), Environment.DEFAULT_LAYER, null);
+        assertTrue(source.rules.get(0).selector.matches(e));
+        source.rules.get(0).declaration.execute(e);
+        assertEquals(Functions.join(",", "Alpha", "Beta"), e.getCascade(Environment.DEFAULT_LAYER).get("sorted", null, String.class));
+    }
+
+    @Test
     public void testCountRoles() throws Exception {
         DataSet ds = new DataSet();
         Way way1 = TestUtils.newWay("highway=residential name=1",
@@ -445,6 +461,15 @@
         /* Check with non-relation */
         e = new Environment(way1, new MultiCascade(), Environment.DEFAULT_LAYER, null);
         assertEquals(0, Functions.count_roles(e, "from", "to"));
+
+        /* Check with actual call to mapcss functions */
+        MapCSSStyleSource source = new MapCSSStyleSource("relation[type=destination_sign] {roles: count_roles(\"from\");}");
+        source.loadStyleSource();
+        assertEquals(1, source.rules.size());
+        e = new Environment(rel1, new MultiCascade(), Environment.DEFAULT_LAYER, null);
+        assertTrue(source.rules.get(0).selector.matches(e));
+        source.rules.get(0).declaration.execute(e);
+        assertEquals((Integer) 1, e.getCascade(Environment.DEFAULT_LAYER).get("roles", null, Integer.class));
     }
 
     @Test
