Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java	(revision 3870)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java	(revision 3871)
@@ -13,4 +13,6 @@
 import java.awt.Rectangle;
 import java.awt.TexturePaint;
+import java.awt.font.FontRenderContext;
+import java.awt.font.LineMetrics;
 import java.awt.geom.GeneralPath;
 import java.awt.geom.Rectangle2D;
@@ -33,5 +35,8 @@
 import org.openstreetmap.josm.gui.NavigatableComponent;
 import org.openstreetmap.josm.gui.mappaint.NodeElemStyle;
+import org.openstreetmap.josm.gui.mappaint.NodeElemStyle.HorizontalTextAlignment;
 import org.openstreetmap.josm.gui.mappaint.NodeElemStyle.Symbol;
+import org.openstreetmap.josm.gui.mappaint.NodeElemStyle.TextElement;
+import org.openstreetmap.josm.gui.mappaint.NodeElemStyle.VerticalTextAlignment;
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.LanguageInfo;
@@ -188,5 +193,5 @@
     }
 
-    public void drawNodeIcon(Node n, ImageIcon icon, float iconAlpha, boolean selected, boolean member, String name) {
+    public void drawNodeIcon(Node n, ImageIcon icon, float iconAlpha, boolean selected, boolean member, TextElement text) {
         Point p = nc.getPoint(n);
         if ((p.x < 0) || (p.y < 0) || (p.x > nc.getWidth()) || (p.y > nc.getHeight())) return;
@@ -198,15 +203,5 @@
         icon.paintIcon ( nc, g, p.x-w/2, p.y-h/2 );
         g.setPaintMode();
-        if(name != null) {
-            if (inactive || n.isDisabled()) {
-                g.setColor(inactiveColor);
-            } else {
-                g.setColor(textColor);
-            }
-            Font defaultFont = g.getFont();
-            g.setFont (orderFont);
-            g.drawString (name, p.x+w/2+2, p.y+h/2+2);
-            g.setFont(defaultFont);
-        }
+        drawNodeText(n, text, p, w/2, h/2);
         if (selected || member)
         {
@@ -216,33 +211,46 @@
     }
 
-    public void drawNodeSymbol(Node n, Symbol s, boolean selected, boolean member, String name) {
+    public void drawNodeSymbol(Node n, Symbol s, boolean selected, boolean member, TextElement text) {
         Point p = nc.getPoint(n);
         if ((p.x < 0) || (p.y < 0) || (p.x > nc.getWidth()) || (p.y > nc.getHeight())) return;
-        int radius = (int) (s.size / 2);
+        int radius = s.size / 2;
 
         if (s.fillColor != null) {
-            g.setColor(s.fillColor);
+            if (inactive || n.isDisabled()) {
+                g.setColor(inactiveColor);
+            } else {
+                g.setColor(s.fillColor);
+            }
             switch (s.symbol) {
+                case SQUARE:
+                    g.fillRect(p.x - radius, p.y - radius, s.size, s.size);
+                    break;
                 case CIRCLE:
-                    g.fillOval(p.x - radius, p.y - radius, (int) s.size, (int) s.size);
+                    g.fillOval(p.x - radius, p.y - radius, s.size, s.size);
                     break;
-                case SQUARE:
-                    g.fillRect(p.x - radius, p.y - radius, (int) s.size, (int) s.size);
-                    break;
+                default:
+                    throw new AssertionError();
             }
         }
         if (s.stroke != null) {
             g.setStroke(s.stroke);
-            g.setColor(s.strokeColor);
+            if (inactive || n.isDisabled()) {
+                g.setColor(inactiveColor);
+            } else {
+                g.setColor(s.strokeColor);
+            }
             switch (s.symbol) {
+                case SQUARE:
+                    g.drawRect(p.x - radius, p.y - radius, s.size - 1, s.size - 1);
+                    break;
                 case CIRCLE:
-                    g.drawOval(p.x - radius, p.y - radius, (int) s.size - 1, (int) s.size - 1);
+                    g.drawOval(p.x - radius, p.y - radius, s.size - 1, s.size - 1);
                     break;
-                case SQUARE:
-                    g.drawRect(p.x - radius, p.y - radius, (int) s.size - 1, (int) s.size - 1);
-                    break;
+                default:
+                    throw new AssertionError();
             }
             g.setStroke(new BasicStroke());
         }
+        drawNodeText(n, text, p, radius, radius);
     }
 
@@ -253,5 +261,5 @@
      * @param color The color of the node.
      */
-    public void drawNode(Node n, Color color, int size, boolean fill, String name) {
+    public void drawNode(Node n, Color color, int size, boolean fill, TextElement text) {
         if (size > 1) {
             Point p = nc.getPoint(n);
@@ -270,16 +278,67 @@
             }
 
-            if(name != null)            {
-                if (inactive || n.isDisabled()) {
-                    g.setColor(inactiveColor);
-                } else {
-                    g.setColor(textColor);
-                }
-                Font defaultFont = g.getFont();
-                g.setFont (orderFont);
-                g.drawString (name, p.x+radius+2, p.y+radius+2);
-                g.setFont(defaultFont);
-            }
-        }
+            drawNodeText(n, text, p, radius, radius + 4);
+        }
+    }
+
+    private void drawNodeText(Node n, TextElement text, Point p, int w_half, int h_half) {
+        if (!isShowNames() || text == null)
+            return;
+
+        String s = text.textKey == null ? getNodeName(n) : n.get(text.textKey);
+        if (s == null)
+            return;
+
+        if (inactive || n.isDisabled()) {
+            g.setColor(inactiveColor);
+        } else {
+            g.setColor(text.color);
+        }
+        Font defaultFont = g.getFont();
+        g.setFont(text.font);
+
+        int x = p.x + text.xOffset;
+        int y = p.y + text.yOffset;
+        /**
+         *
+         *       left-above __center-above___ right-above
+         *         left-top|                 |right-top
+         *                 |                 |
+         *      left-center|  center-center  |right-center
+         *                 |                 |
+         *      left-bottom|_________________|right-bottom
+         *       left-below   center-below    right-below
+         *
+         */
+        if (text.hAlign == HorizontalTextAlignment.RIGHT) {
+            x += w_half + 2;
+        } else {
+            FontRenderContext frc = g.getFontRenderContext();
+            Rectangle2D bounds = text.font.getStringBounds(s, frc);
+            int textWidth = (int) bounds.getWidth();
+            if (text.hAlign == HorizontalTextAlignment.CENTER) {
+                x -= textWidth / 2;
+            } else if (text.hAlign == HorizontalTextAlignment.LEFT) {
+                x -= w_half + 4 + textWidth;
+            } else throw new AssertionError();
+        }
+
+        if (text.vAlign == VerticalTextAlignment.BOTTOM) {
+            y += h_half - 2;
+        } else {
+            FontRenderContext frc = g.getFontRenderContext();
+            LineMetrics metrics = text.font.getLineMetrics(s, frc);
+            if (text.vAlign == VerticalTextAlignment.ABOVE) {
+                y -= h_half + metrics.getDescent();
+            } else if (text.vAlign == VerticalTextAlignment.TOP) {
+                y -= h_half - metrics.getAscent();
+            } else if (text.vAlign == VerticalTextAlignment.CENTER) {
+                y += (metrics.getAscent() - metrics.getDescent()) / 2;
+            } else if (text.vAlign == VerticalTextAlignment.BELOW) {
+                y += h_half + metrics.getAscent();
+            } else throw new AssertionError();
+        }
+        g.drawString(s, x, y);
+        g.setFont(defaultFont);
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/Cascade.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/Cascade.java	(revision 3870)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/Cascade.java	(revision 3871)
@@ -9,4 +9,5 @@
 
 import org.openstreetmap.josm.gui.mappaint.mapcss.CSSColors;
+import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -183,5 +184,5 @@
                 res.append(Arrays.toString((float[]) val));
             } else if (val instanceof Color) {
-                res.append(String.format("#%x", ((Color) val).getRGB()));
+                res.append(Utils.toString((Color)val));
             } else {
                 res.append(val+"");
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/LineElemStyle.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/LineElemStyle.java	(revision 3870)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/LineElemStyle.java	(revision 3871)
@@ -164,4 +164,7 @@
 
         float miterlimit = c.get(prefix + "miterlimit", 10f, Float.class);
+        if (miterlimit < 1f) {
+            miterlimit = 10f;
+        }
 
         BasicStroke line = new BasicStroke(width, cap, join, miterlimit, dashes, dashesOffset);
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/NodeElemStyle.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/NodeElemStyle.java	(revision 3870)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/NodeElemStyle.java	(revision 3871)
@@ -6,4 +6,5 @@
 import java.awt.BasicStroke;
 import java.awt.Color;
+import java.awt.Font;
 import java.awt.Stroke;
 
@@ -17,5 +18,7 @@
 import org.openstreetmap.josm.data.osm.visitor.paint.MapPaintSettings;
 import org.openstreetmap.josm.data.osm.visitor.paint.MapPainter;
+import org.openstreetmap.josm.data.osm.visitor.paint.PaintColors;
 import org.openstreetmap.josm.gui.mappaint.MapPaintStyles.IconReference;
+import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -24,20 +27,24 @@
  */
 public class NodeElemStyle extends ElemStyle {
-    public boolean annotate;
-    public String annotation_key;
+
     public ImageIcon icon;
     public int iconAlpha;
     public Symbol symbol;
+    public TextElement text;
 
     private ImageIcon disabledIcon;
+
+    public enum SymbolShape { SQUARE, CIRCLE }
+    public enum HorizontalTextAlignment { LEFT, CENTER, RIGHT }
+    public enum VerticalTextAlignment { ABOVE, TOP, CENTER, BOTTOM, BELOW }
 
     public static class Symbol {
         public SymbolShape symbol;
-        public float size;
+        public int size;
         public Stroke stroke;
         public Color strokeColor;
         public Color fillColor;
 
-        public Symbol(SymbolShape symbol, float size, Stroke stroke, Color strokeColor, Color fillColor) {
+        public Symbol(SymbolShape symbol, int size, Stroke stroke, Color strokeColor, Color fillColor) {
             if (stroke != null && strokeColor == null)
                 throw new IllegalArgumentException();
@@ -67,5 +74,5 @@
             int hash = 7;
             hash = 67 * hash + symbol.hashCode();
-            hash = 67 * hash + Float.floatToIntBits(size);
+            hash = 67 * hash + size;
             hash = 67 * hash + (stroke != null ? stroke.hashCode() : 0);
             hash = 67 * hash + (strokeColor != null ? strokeColor.hashCode() : 0);
@@ -81,19 +88,76 @@
         }
     }
+
+    public static class TextElement {
+        public String textKey;
+        public HorizontalTextAlignment hAlign;
+        public VerticalTextAlignment vAlign;
+        public Font font;
+        public int xOffset;
+        public int yOffset;
+        public Color color;
+
+        public TextElement(String textKey, HorizontalTextAlignment hAlign, VerticalTextAlignment vAlign, Font font, int xOffset, int yOffset, Color color) {
+            CheckParameterUtil.ensureParameterNotNull(hAlign);
+            CheckParameterUtil.ensureParameterNotNull(vAlign);
+            CheckParameterUtil.ensureParameterNotNull(font);
+            CheckParameterUtil.ensureParameterNotNull(color);
+            this.textKey = textKey;
+            this.hAlign = hAlign;
+            this.vAlign = vAlign;
+            this.font = font;
+            this.xOffset = xOffset;
+            this.yOffset = yOffset;
+            this.color = color;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == null || getClass() != obj.getClass())
+                return false;
+            final TextElement other = (TextElement) obj;
+            return  equal(textKey, other.textKey) &&
+                    hAlign == other.hAlign &&
+                    vAlign == other.vAlign &&
+                    equal(font, other.font) &&
+                    xOffset == other.xOffset &&
+                    yOffset == other.yOffset &&
+                    equal(color, other.color);
+        }
+
+        @Override
+        public int hashCode() {
+            int hash = 3;
+            hash = 79 * hash + (textKey != null ? textKey.hashCode() : 0);
+            hash = 79 * hash + hAlign.hashCode();
+            hash = 79 * hash + vAlign.hashCode();
+            hash = 79 * hash + font.hashCode();
+            hash = 79 * hash + xOffset;
+            hash = 79 * hash + yOffset;
+            hash = 79 * hash + color.hashCode();
+            return hash;
+        }
+    }
     
-    public enum SymbolShape { SQUARE, CIRCLE }
-
-    public static final NodeElemStyle SIMPLE_NODE_ELEMSTYLE = new NodeElemStyle(Cascade.EMPTY_CASCADE, true, null, null, 0, null);
-
-    protected NodeElemStyle(Cascade c, boolean annotate, String annotation_key, ImageIcon icon, int iconAlpha, Symbol symbol) {
+    public static final NodeElemStyle SIMPLE_NODE_ELEMSTYLE;
+    static {
+        Cascade c = new Cascade(false);
+        c.put("text", "auto");
+        SIMPLE_NODE_ELEMSTYLE = create(c, true);
+    }
+
+    protected NodeElemStyle(Cascade c, ImageIcon icon, int iconAlpha, Symbol symbol, TextElement text) {
         super(c);
-        this.annotate = annotate;
-        this.annotation_key = annotation_key;
         this.icon = icon;
         this.iconAlpha = iconAlpha;
         this.symbol = symbol;
+        this.text = text;
     }
 
     public static NodeElemStyle create(Cascade c) {
+        return create(c, false);
+    }
+
+    private static NodeElemStyle create(Cascade c, boolean allowOnlyText) {
         IconReference iconRef = c.get("icon-image", null, IconReference.class);
         ImageIcon icon = null;
@@ -109,51 +173,98 @@
             }
         } else {
-            SymbolShape shape;
-            String shapeStr = c.get("symbol-shape", null, String.class);
-            if (equal(shapeStr, "square")) {
-                shape = SymbolShape.SQUARE;
-            } else if (equal(shapeStr, "circle")) {
-                shape = SymbolShape.CIRCLE;
-            } else
-                return null;
-
-            Float size = c.get("symbol-size", null, Float.class);
-            if (size == null || size <= 0)
-                return null;
-
-            Float strokeWidth = c.get("symbol-stroke-width", null, Float.class);
-            Color strokeColor = c.get("symbol-stroke-color", null, Color.class);
-            if (strokeColor != null) {
-                float strokeAlpha = c.get("symbol-stroke-opacity", 1f, Float.class);
-                strokeColor = new Color(strokeColor.getRed(), strokeColor.getGreen(),
-                        strokeColor.getBlue(), Utils.color_float2int(strokeAlpha));
-            }
-            Stroke stroke = null;
-            if (strokeWidth != null && strokeWidth > 0 && strokeColor != null) {
-                stroke = new BasicStroke(strokeWidth);
-            }
-
-            Color fillColor = c.get("symbol-fill-color", null, Color.class);
-            if (fillColor != null) {
-                float fillAlpha = c.get("symbol-fill-opacity", 1f, Float.class);
-                fillColor = new Color(fillColor.getRed(), fillColor.getGreen(),
-                        fillColor.getBlue(), Utils.color_float2int(fillAlpha));
-            }
-
-            if ((stroke == null || strokeColor == null) && fillColor == null)
-                return null;
-
-            symbol = new Symbol(shape, size, stroke, strokeColor, fillColor);
-        }
-
-        String text = c.get("text", null, String.class);
-
-        boolean annotate = text != null;
-        String annotation_key = null;
-
-        if (annotate && !"auto".equalsIgnoreCase(text)) {
-            annotation_key = text;
-        }
-        return new NodeElemStyle(c, annotate, annotation_key, icon, iconAlpha, symbol);
+            symbol = createSymbol(c);
+        }
+
+        if (icon == null && symbol == null && !allowOnlyText)
+            return null;
+
+        TextElement text = null;
+        String textStr = c.get("text", null, String.class);
+        if (textStr != null) {
+            String textKey = null;
+            if (!"auto".equalsIgnoreCase(textStr)) {
+                textKey = textStr;
+            }
+            HorizontalTextAlignment hAlign = HorizontalTextAlignment.RIGHT;
+            String hAlignStr = c.get("text-anchor-horizontal", null, String.class);
+            if (equal(hAlignStr, "left")) {
+                hAlign = HorizontalTextAlignment.LEFT;
+            } else if (equal(hAlignStr, "center")) {
+                hAlign = HorizontalTextAlignment.CENTER;
+            } else if (equal(hAlignStr, "right")) {
+                hAlign = HorizontalTextAlignment.RIGHT;
+            }
+            VerticalTextAlignment vAlign = VerticalTextAlignment.BOTTOM;
+            String vAlignStr = c.get("text-anchor-vertical", null, String.class);
+            if (equal(vAlignStr, "above")) {
+                vAlign = VerticalTextAlignment.ABOVE;
+            } else if (equal(vAlignStr, "top")) {
+                vAlign = VerticalTextAlignment.TOP;
+            } else if (equal(vAlignStr, "center")) {
+                vAlign = VerticalTextAlignment.CENTER;
+            } else if (equal(vAlignStr, "bottom")) {
+                vAlign = VerticalTextAlignment.BOTTOM;
+            } else if (equal(vAlignStr, "below")) {
+                vAlign = VerticalTextAlignment.BELOW;
+            }
+            String name = c.get("font-family", Main.pref.get("mappaint.font", "Helvetica"), String.class);
+            float size = c.get("font-size", (float) Main.pref.getInteger("mappaint.fontsize", 8), Float.class);
+            int weight = Font.PLAIN;
+            String weightStr = c.get("font-wheight", null, String.class);
+            if (equal(weightStr, "bold")) {
+                weight = Font.BOLD;
+            }
+            int style = Font.PLAIN;
+            String styleStr = c.get("font-style", null, String.class);
+            if (equal(styleStr, "italic")) {
+                style = Font.ITALIC;
+            }
+            Font font = new Font(name, weight | style, Math.round(size));
+            int xOffset = c.get("text-offset-x", 0f, Float.class).intValue();
+            int yOffset = c.get("text-offset-y", 0f, Float.class).intValue();
+            Color color = c.get("text-color", PaintColors.TEXT.get(), Color.class);
+            text = new TextElement(textKey, hAlign, vAlign, font, xOffset, yOffset, color);
+        }
+        
+        return new NodeElemStyle(c, icon, iconAlpha, symbol, text);
+    }
+
+    private static Symbol createSymbol(Cascade c) {
+        SymbolShape shape;
+        String shapeStr = c.get("symbol-shape", null, String.class);
+        if (equal(shapeStr, "square")) {
+            shape = SymbolShape.SQUARE;
+        } else if (equal(shapeStr, "circle")) {
+            shape = SymbolShape.CIRCLE;
+        } else
+            return null;
+
+        Float size = c.get("symbol-size", null, Float.class);
+        if (size == null || size <= 0)
+            return null;
+
+        Float strokeWidth = c.get("symbol-stroke-width", null, Float.class);
+        Color strokeColor = c.get("symbol-stroke-color", null, Color.class);
+        if (strokeColor != null) {
+            float strokeAlpha = c.get("symbol-stroke-opacity", 1f, Float.class);
+            strokeColor = new Color(strokeColor.getRed(), strokeColor.getGreen(),
+                    strokeColor.getBlue(), Utils.color_float2int(strokeAlpha));
+        }
+        Stroke stroke = null;
+        if (strokeWidth != null && strokeWidth > 0 && strokeColor != null) {
+            stroke = new BasicStroke(strokeWidth);
+        }
+
+        Color fillColor = c.get("symbol-fill-color", null, Color.class);
+        if (fillColor != null) {
+            float fillAlpha = c.get("symbol-fill-opacity", 1f, Float.class);
+            fillColor = new Color(fillColor.getRed(), fillColor.getGreen(),
+                    fillColor.getBlue(), Utils.color_float2int(fillAlpha));
+        }
+
+        if ((stroke == null || strokeColor == null) && fillColor == null)
+            return null;
+
+        return new Symbol(shape, size.intValue(), stroke, strokeColor, fillColor);
     }
 
@@ -164,10 +275,10 @@
             if (icon != null && painter.isShowIcons()) {
                 painter.drawNodeIcon(n, (painter.isInactive() || n.isDisabled()) ? getDisabledIcon() : icon,
-                        Utils.color_int2float(iconAlpha), selected, member, getName(n, painter));
+                        Utils.color_int2float(iconAlpha), selected, member, text);
             } else if (symbol != null) {
-                painter.drawNodeSymbol(n, symbol, selected, member, getName(n, painter));
+                painter.drawNodeSymbol(n, symbol, selected, member, text);
             } else {
                 if (n.isHighlighted()) {
-                    painter.drawNode(n, settings.getHighlightColor(), settings.getSelectedNodeSize(), settings.isFillSelectedNode(), getName(n, painter));
+                    painter.drawNode(n, settings.getHighlightColor(), settings.getSelectedNodeSize(), settings.isFillSelectedNode(), text);
                 } else {
                     Color color;
@@ -204,5 +315,5 @@
                                             settings.isFillUnselectedNode();
 
-                    painter.drawNode(n, color, size, fill, getName(n, painter));
+                    painter.drawNode(n, color, size, fill, text);
                 }
             }
@@ -220,23 +331,11 @@
     }
 
-    protected String getName(Node n, MapPainter painter) {
-        if (painter.isShowNames() && annotate) {
-            if (annotation_key != null) {
-                return n.get(annotation_key);
-            } else {
-                return painter.getNodeName(n);
-            }
-        }
-        return null;
-    }
-
     @Override
     public int hashCode() {
         int hash = super.hashCode();
-        hash = 17 * hash + (annotate ? 1 : 0);
-        hash = 17 * hash + (annotation_key != null ? annotation_key.hashCode() : 0);
         hash = 17 * hash + (icon != null ? icon.getImage().hashCode() : 0);
-        hash = 17 * hash + this.iconAlpha;
-        hash = 17 * hash + (this.symbol != null ? this.symbol.hashCode() : 0);
+        hash = 17 * hash + iconAlpha;
+        hash = 17 * hash + (symbol != null ? symbol.hashCode() : 0);
+        hash = 17 * hash + (text != null ? text.hashCode() : 0);
         return hash;
     }
@@ -253,11 +352,9 @@
         if (icon != other.icon && (icon == null || other.icon == null || icon.getImage() != other.icon.getImage()))
             return false;
-        if (annotate != other.annotate)
-            return false;
-        if (!equal(annotation_key, annotation_key))
-            return false;
         if (this.iconAlpha != other.iconAlpha)
             return false;
         if (!equal(symbol, other.symbol))
+            return false;
+        if (!equal(text, other.text))
             return false;
         return true;
@@ -267,6 +364,6 @@
     @Override
     public String toString() {
-        return "NodeElemStyle{" + super.toString() + "annotate=" + annotate + " annotation_key=" + annotation_key +
-                (icon != null ? (" icon=" + icon + " iconAlpha=" + iconAlpha) : "") +
+        return "NodeElemStyle{" + super.toString() +
+                (icon != null ? ("icon=" + icon + " iconAlpha=" + iconAlpha) : "") +
                 (symbol != null ? (" symbol=[" + symbol + "]") : "") + '}';
     }
Index: trunk/src/org/openstreetmap/josm/tools/CheckParameterUtil.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/CheckParameterUtil.java	(revision 3870)
+++ trunk/src/org/openstreetmap/josm/tools/CheckParameterUtil.java	(revision 3871)
@@ -33,4 +33,12 @@
 
     /**
+     * can find line number in the stack trace, so parameter name is optional
+     */
+    public static void ensureParameterNotNull(Object value) {
+        if (value == null)
+            throw new IllegalArgumentException("Parameter must not be null");
+    }
+
+    /**
      * Ensures that <code>id</code> is non-null primitive id of type {@see OsmPrimitiveType#NODE}
      *
