Index: trunk/src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java	(revision 13667)
+++ trunk/src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java	(revision 13668)
@@ -12,5 +12,4 @@
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
@@ -467,11 +466,5 @@
     }
 
-    /**
-     * Calls the visitor for every key/value pair of this primitive.
-     *
-     * @param visitor The visitor to call.
-     * @see #getKeys()
-     * @since 8742
-     */
+    @Override
     public void visitKeys(KeyValueVisitor visitor) {
         final String[] keys = this.keys;
@@ -769,68 +762,3 @@
         return getName();
     }
-
-    /**
-     * Tests whether this primitive contains a tag consisting of {@code key} and {@code value}.
-     * @param key the key forming the tag.
-     * @param value value forming the tag.
-     * @return true if primitive contains a tag consisting of {@code key} and {@code value}.
-     */
-    public boolean hasTag(String key, String value) {
-        return Objects.equals(value, get(key));
-    }
-
-    /**
-     * Tests whether this primitive contains a tag consisting of {@code key} and any of {@code values}.
-     * @param key the key forming the tag.
-     * @param values one or many values forming the tag.
-     * @return true if primitive contains a tag consisting of {@code key} and any of {@code values}.
-     */
-    public boolean hasTag(String key, String... values) {
-        return hasTag(key, Arrays.asList(values));
-    }
-
-    /**
-     * Tests whether this primitive contains a tag consisting of {@code key} and any of {@code values}.
-     * @param key the key forming the tag.
-     * @param values one or many values forming the tag.
-     * @return true if primitive contains a tag consisting of {@code key} and any of {@code values}.
-     */
-    public boolean hasTag(String key, Collection<String> values) {
-        return values.contains(get(key));
-    }
-
-    /**
-     * Tests whether this primitive contains a tag consisting of {@code key} and a value different from {@code value}.
-     * @param key the key forming the tag.
-     * @param value value not forming the tag.
-     * @return true if primitive contains a tag consisting of {@code key} and a value different from {@code value}.
-     * @since 11608
-     */
-    public boolean hasTagDifferent(String key, String value) {
-        String v = get(key);
-        return v != null && !v.equals(value);
-    }
-
-    /**
-     * Tests whether this primitive contains a tag consisting of {@code key} and none of {@code values}.
-     * @param key the key forming the tag.
-     * @param values one or many values forming the tag.
-     * @return true if primitive contains a tag consisting of {@code key} and none of {@code values}.
-     * @since 11608
-     */
-    public boolean hasTagDifferent(String key, String... values) {
-        return hasTagDifferent(key, Arrays.asList(values));
-    }
-
-    /**
-     * Tests whether this primitive contains a tag consisting of {@code key} and none of {@code values}.
-     * @param key the key forming the tag.
-     * @param values one or many values forming the tag.
-     * @return true if primitive contains a tag consisting of {@code key} and none of {@code values}.
-     * @since 11608
-     */
-    public boolean hasTagDifferent(String key, Collection<String> values) {
-        String v = get(key);
-        return v != null && !values.contains(v);
-    }
 }
Index: trunk/src/org/openstreetmap/josm/data/osm/Tagged.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/Tagged.java	(revision 13667)
+++ trunk/src/org/openstreetmap/josm/data/osm/Tagged.java	(revision 13668)
@@ -2,6 +2,8 @@
 package org.openstreetmap.josm.data.osm;
 
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Map;
+import java.util.Objects;
 
 /**
@@ -35,4 +37,15 @@
 
     /**
+     * Calls the visitor for every key/value pair.
+     *
+     * @param visitor The visitor to call.
+     * @see #getKeys()
+     * @since 13668
+     */
+    default void visitKeys(KeyValueVisitor visitor) {
+        getKeys().forEach((k, v) -> visitor.visitKeyValue(this, k, v));
+    }
+
+    /**
      * Sets a key/value pairs
      *
@@ -101,4 +114,72 @@
 
     /**
+     * Tests whether this primitive contains a tag consisting of {@code key} and {@code value}.
+     * @param key the key forming the tag.
+     * @param value value forming the tag.
+     * @return true if primitive contains a tag consisting of {@code key} and {@code value}.
+     * @since 13668
+     */
+    default boolean hasTag(String key, String value) {
+        return Objects.equals(value, get(key));
+    }
+
+    /**
+     * Tests whether this primitive contains a tag consisting of {@code key} and any of {@code values}.
+     * @param key the key forming the tag.
+     * @param values one or many values forming the tag.
+     * @return true if primitive contains a tag consisting of {@code key} and any of {@code values}.
+     * @since 13668
+     */
+    default boolean hasTag(String key, String... values) {
+        return hasTag(key, Arrays.asList(values));
+    }
+
+    /**
+     * Tests whether this primitive contains a tag consisting of {@code key} and any of {@code values}.
+     * @param key the key forming the tag.
+     * @param values one or many values forming the tag.
+     * @return true if primitive contains a tag consisting of {@code key} and any of {@code values}.
+     * @since 13668
+     */
+    default boolean hasTag(String key, Collection<String> values) {
+        return values.contains(get(key));
+    }
+
+    /**
+     * Tests whether this primitive contains a tag consisting of {@code key} and a value different from {@code value}.
+     * @param key the key forming the tag.
+     * @param value value not forming the tag.
+     * @return true if primitive contains a tag consisting of {@code key} and a value different from {@code value}.
+     * @since 13668
+     */
+    default boolean hasTagDifferent(String key, String value) {
+        String v = get(key);
+        return v != null && !v.equals(value);
+    }
+
+    /**
+     * Tests whether this primitive contains a tag consisting of {@code key} and none of {@code values}.
+     * @param key the key forming the tag.
+     * @param values one or many values forming the tag.
+     * @return true if primitive contains a tag consisting of {@code key} and none of {@code values}.
+     * @since 13668
+     */
+    default boolean hasTagDifferent(String key, String... values) {
+        return hasTagDifferent(key, Arrays.asList(values));
+    }
+
+    /**
+     * Tests whether this primitive contains a tag consisting of {@code key} and none of {@code values}.
+     * @param key the key forming the tag.
+     * @param values one or many values forming the tag.
+     * @return true if primitive contains a tag consisting of {@code key} and none of {@code values}.
+     * @since 13668
+     */
+    default boolean hasTagDifferent(String key, Collection<String> values) {
+        String v = get(key);
+        return v != null && !values.contains(v);
+    }
+
+    /**
      * Replies the set of keys
      *
