Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Functions.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Functions.java	(revision 15245)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Functions.java	(revision 15246)
@@ -50,5 +50,5 @@
  * immediately. Add the annotation {@link NullableArguments} to allow null arguments.
  * Every method must be static.
- * 
+ *
  * @since 15245 (extracted from {@link ExpressionFactory})
  */
@@ -767,4 +767,59 @@
 
     /**
+     * Returns the OSM user name who last touched the current object.
+     * @param env the environment
+     * @return the OSM user name who last touched the current object
+     * @see IPrimitive#getUser
+     * @since 15246
+     */
+    public static String osm_user_name(final Environment env) { // NO_UCD (unused code)
+        return env.osm.getUser().getName();
+    }
+
+    /**
+     * Returns the OSM user id who last touched the current object.
+     * @param env the environment
+     * @return the OSM user id who last touched the current object
+     * @see IPrimitive#getUser
+     * @since 15246
+     */
+    public static long osm_user_id(final Environment env) { // NO_UCD (unused code)
+        return env.osm.getUser().getId();
+    }
+
+    /**
+     * Returns the version number of the current object.
+     * @param env the environment
+     * @return the version number of the current object
+     * @see IPrimitive#getVersion
+     * @since 15246
+     */
+    public static int osm_version(final Environment env) { // NO_UCD (unused code)
+        return env.osm.getVersion();
+    }
+
+    /**
+     * Returns the id of the changeset the current object was last uploaded to.
+     * @param env the environment
+     * @return the id of the changeset the current object was last uploaded to
+     * @see IPrimitive#getChangesetId
+     * @since 15246
+     */
+    public static int osm_changeset_id(final Environment env) { // NO_UCD (unused code)
+        return env.osm.getChangesetId();
+    }
+
+    /**
+     * Returns the time of last modification to the current object, as timestamp.
+     * @param env the environment
+     * @return the time of last modification to the current object, as timestamp
+     * @see IPrimitive#getRawTimestamp
+     * @since 15246
+     */
+    public static int osm_timestamp(final Environment env) { // NO_UCD (unused code)
+        return env.osm.getRawTimestamp();
+    }
+
+    /**
      * 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>, <code>{1}</code>, …
Index: /trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/FunctionsTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/FunctionsTest.java	(revision 15246)
+++ /trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/FunctionsTest.java	(revision 15246)
@@ -0,0 +1,91 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.mappaint.mapcss;
+
+import static org.junit.Assert.assertEquals;
+import static org.openstreetmap.josm.data.osm.OsmPrimitiveType.NODE;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.openstreetmap.josm.TestUtils;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
+import org.openstreetmap.josm.data.osm.User;
+import org.openstreetmap.josm.gui.mappaint.Environment;
+import org.openstreetmap.josm.testutils.JOSMTestRules;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
+/**
+ * Unit tests of {@link Functions}.
+ */
+public class FunctionsTest {
+
+    /**
+     * Setup rule
+     */
+    @Rule
+    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
+    public JOSMTestRules test = new JOSMTestRules();
+
+    private static class EnvBuilder {
+        private final OsmPrimitive osm;
+
+        EnvBuilder(OsmPrimitiveType type) {
+            switch (type) {
+                case NODE : osm = TestUtils.newNode(""); break;
+                case WAY : osm = TestUtils.newWay(""); break;
+                case RELATION : osm = TestUtils.newRelation(""); break;
+                default: throw new IllegalArgumentException();
+            }
+        }
+
+        EnvBuilder setUser(User user) {
+            osm.setUser(user);
+            return this;
+        }
+
+        Environment build() {
+            return new Environment(osm);
+        }
+    }
+
+    /**
+     * Unit test of {@link Functions#osm_user_name}.
+     */
+    @Test
+    public void testOsmUserName() {
+        assertEquals("<anonymous>", Functions.osm_user_name(new EnvBuilder(NODE).setUser(User.getAnonymous()).build()));
+    }
+
+    /**
+     * Unit test of {@link Functions#osm_user_id}.
+     */
+    @Test
+    public void testOsmUserId() {
+        assertEquals(-1, Functions.osm_user_id(new EnvBuilder(NODE).setUser(User.getAnonymous()).build()));
+    }
+
+    /**
+     * Unit test of {@link Functions#osm_version}.
+     */
+    @Test
+    public void testOsmVersion() {
+        assertEquals(0, Functions.osm_version(new EnvBuilder(NODE).build()));
+    }
+
+    /**
+     * Unit test of {@link Functions#osm_changeset_id}.
+     */
+    @Test
+    public void testOsmChangesetId() {
+        assertEquals(0, Functions.osm_changeset_id(new EnvBuilder(NODE).build()));
+    }
+
+    /**
+     * Unit test of {@link Functions#osm_timestamp}.
+     */
+    @Test
+    public void testOsmTimestamp() {
+        assertEquals(0, Functions.osm_timestamp(new EnvBuilder(NODE).build()));
+    }
+}
