Index: /trunk/src/org/openstreetmap/josm/command/ChangePropertyKeyCommand.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/command/ChangePropertyKeyCommand.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/command/ChangePropertyKeyCommand.java	(revision 11608)
@@ -93,7 +93,7 @@
             return false; // save old
         for (OsmPrimitive osm : objects) {
-            if (osm.hasKey(key) || osm.hasKey(newKey)) {
+            String oldValue = osm.get(key);
+            if (oldValue != null || osm.hasKey(newKey)) {
                 osm.setModified(true);
-                String oldValue = osm.get(key);
                 osm.put(newKey, oldValue);
                 osm.remove(key);
Index: /trunk/src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java	(revision 11608)
@@ -706,6 +706,5 @@
      * Replies true, if the map of key/value pairs of this primitive is not empty.
      *
-     * @return true, if the map of key/value pairs of this primitive is not empty; false
-     *   otherwise
+     * @return true, if the map of key/value pairs of this primitive is not empty; false otherwise
      */
     @Override
@@ -718,6 +717,7 @@
      *
      * @param key the key
-     * @return true, if his primitive has a tag with key <code>key</code>
-     */
+     * @return true, if this primitive has a tag with key <code>key</code>
+     */
+    @Override
     public boolean hasKey(String key) {
         return key != null && indexOfKey(keys, key) >= 0;
@@ -728,5 +728,5 @@
      *
      * @param keys the keys
-     * @return true, if his primitive has a tag with any of the <code>keys</code>
+     * @return true, if this primitive has a tag with any of the <code>keys</code>
      * @since 11587
      */
@@ -758,8 +758,8 @@
 
     /**
-     * Tests whether this primitive contains a tag consisting of {@code key} and {@code values}.
+     * 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 iff primitive contains a tag consisting of {@code key} and {@code value}.
+     * @return true if primitive contains a tag consisting of {@code key} and {@code value}.
      */
     public boolean hasTag(String key, String value) {
@@ -781,8 +781,43 @@
      * @param key the key forming the tag.
      * @param values one or many values forming the tag.
-     * @return true iff primitive contains a tag consisting of {@code key} and any of {@code values}.
+     * @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/OsmPrimitive.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 11608)
@@ -1353,7 +1353,8 @@
      */
     public final boolean hasAreaTags() {
-        return hasKey("landuse", "amenity", "leisure", "building", "building:part")
-                || "yes".equals(get("area"))
-                || "riverbank".equals(get("waterway"))
+        return hasKey("landuse", "amenity", "building", "building:part")
+                || hasTag("area", "yes")
+                || hasTag("waterway", "riverbank")
+                || hasTagDifferent("leisure", "picnic_table", "slipway", "firepit")
                 || hasTag("natural", "water", "wood", "scrub", "wetland", "grassland", "heath", "rock", "bare_rock",
                                      "sand", "beach", "scree", "bay", "glacier", "shingle", "fell", "reef", "stone",
Index: /trunk/src/org/openstreetmap/josm/data/osm/Tagged.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/Tagged.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/data/osm/Tagged.java	(revision 11608)
@@ -4,8 +4,9 @@
 import java.util.Collection;
 import java.util.Map;
+
 /**
  * Objects implement Tagged if they provide a map of key/value pairs.
  *
- *
+ * @since 2115
  */
 // FIXME: better naming? setTags(), getTags(), getKeys() instead of keySet() ?
@@ -67,4 +68,15 @@
 
     /**
+     * Replies true if there is a tag with key <code>key</code>.
+     *
+     * @param key the key
+     * @return true, if there is a tag with key <code>key</code>
+     * @since 11608
+     */
+    default boolean hasKey(String key) {
+        return get(key) != null;
+    }
+
+    /**
      * Replies the set of keys
      *
Index: /trunk/src/org/openstreetmap/josm/data/osm/history/HistoryNode.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/history/HistoryNode.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/data/osm/history/HistoryNode.java	(revision 11608)
@@ -10,7 +10,6 @@
 
 /**
- * Represents an immutable OSM node in the context of a historical view on
- * OSM data.
- *
+ * Represents an immutable OSM node in the context of a historical view on OSM data.
+ * @since 1670
  */
 public class HistoryNode extends HistoryOsmPrimitive {
Index: /trunk/src/org/openstreetmap/josm/data/osm/history/HistoryOsmPrimitive.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/history/HistoryOsmPrimitive.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/data/osm/history/HistoryOsmPrimitive.java	(revision 11608)
@@ -5,4 +5,5 @@
 
 import java.text.MessageFormat;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
@@ -19,4 +20,5 @@
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
+import org.openstreetmap.josm.data.osm.Tagged;
 import org.openstreetmap.josm.data.osm.User;
 import org.openstreetmap.josm.data.osm.Way;
@@ -24,9 +26,8 @@
 
 /**
- * Represents an immutable OSM primitive in the context of a historical view on
- * OSM data.
- *
+ * Represents an immutable OSM primitive in the context of a historical view on OSM data.
+ * @since 1670
  */
-public abstract class HistoryOsmPrimitive implements Comparable<HistoryOsmPrimitive> {
+public abstract class HistoryOsmPrimitive implements Tagged, Comparable<HistoryOsmPrimitive> {
 
     private long id;
@@ -38,10 +39,4 @@
     private long version;
     private Map<String, String> tags;
-
-    protected final void ensurePositiveLong(long value, String name) {
-        if (value <= 0) {
-            throw new IllegalArgumentException(MessageFormat.format("Parameter ''{0}'' > 0 expected. Got ''{1}''.", name, value));
-        }
-    }
 
     /**
@@ -119,32 +114,66 @@
     }
 
+    /**
+     * Returns the id.
+     * @return the id
+     */
     public long getId() {
         return id;
     }
 
+    /**
+     * Returns the primitive id.
+     * @return the primitive id
+     */
     public PrimitiveId getPrimitiveId() {
         return new SimplePrimitiveId(id, getType());
     }
 
+    /**
+     * Determines if the primitive is still visible.
+     * @return {@code true} if the primitive is still visible
+     */
     public boolean isVisible() {
         return visible;
     }
 
+    /**
+     * Returns the user.
+     * @return the user
+     */
     public User getUser() {
         return user;
     }
 
+    /**
+     * Returns the changeset id.
+     * @return the changeset id
+     */
     public long getChangesetId() {
         return changesetId;
     }
 
+    /**
+     * Returns the timestamp.
+     * @return the timestamp
+     */
     public Date getTimestamp() {
         return timestamp;
     }
 
+    /**
+     * Returns the version.
+     * @return the version
+     */
     public long getVersion() {
         return version;
     }
 
+    protected final void ensurePositiveLong(long value, String name) {
+        if (value <= 0) {
+            throw new IllegalArgumentException(MessageFormat.format("Parameter ''{0}'' > 0 expected. Got ''{1}''.", name, value));
+        }
+    }
+
     public boolean matches(long id, long version) {
         return this.id == id && this.version == version;
@@ -155,4 +184,8 @@
     }
 
+    /**
+     * Returns the primitive type.
+     * @return the primitive type
+     */
     public abstract OsmPrimitiveType getType();
 
@@ -164,16 +197,53 @@
     }
 
-    public void put(String key, String value) {
+    @Override
+    public final void put(String key, String value) {
         tags.put(key, value);
     }
 
-    public String get(String key) {
+    @Override
+    public final String get(String key) {
         return tags.get(key);
     }
 
-    public boolean hasTag(String key) {
-        return tags.get(key) != null;
-    }
-
+    @Override
+    public final boolean hasKey(String key) {
+        return tags.containsKey(key);
+    }
+
+    @Override
+    public final Map<String, String> getKeys() {
+        return getTags();
+    }
+
+    @Override
+    public final void setKeys(Map<String, String> keys) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public final void remove(String key) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public final void removeAll() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public final boolean hasKeys() {
+        return !tags.isEmpty();
+    }
+
+    @Override
+    public final Collection<String> keySet() {
+        return Collections.unmodifiableSet(tags.keySet());
+    }
+
+    /**
+     * Replies the key/value map.
+     * @return the key/value map
+     */
     public Map<String, String> getTags() {
         return Collections.unmodifiableMap(tags);
@@ -272,6 +342,6 @@
     public String toString() {
         return getClass().getSimpleName() + " [version=" + version + ", id=" + id + ", visible=" + visible + ", "
-                + (timestamp != null ? "timestamp=" + timestamp : "") + ", "
-                + (user != null ? "user=" + user + ", " : "") + "changesetId="
+                + (timestamp != null ? ("timestamp=" + timestamp) : "") + ", "
+                + (user != null ? ("user=" + user + ", ") : "") + "changesetId="
                 + changesetId
                 + ']';
Index: /trunk/src/org/openstreetmap/josm/data/osm/history/HistoryRelation.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/history/HistoryRelation.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/data/osm/history/HistoryRelation.java	(revision 11608)
@@ -15,7 +15,6 @@
 
 /**
- * Represents an immutable OSM relation in the context of a historical view on
- * OSM data.
- *
+ * Represents an immutable OSM relation in the context of a historical view on OSM data.
+ * @since 1670
  */
 public class HistoryRelation extends HistoryOsmPrimitive {
Index: /trunk/src/org/openstreetmap/josm/data/osm/history/HistoryWay.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/history/HistoryWay.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/data/osm/history/HistoryWay.java	(revision 11608)
@@ -15,7 +15,6 @@
 
 /**
- * Represents an immutable OSM way in the context of a historical view on
- * OSM data.
- *
+ * Represents an immutable OSM way in the context of a historical view on OSM data.
+ * @since 1670
  */
 public class HistoryWay extends HistoryOsmPrimitive {
Index: /trunk/src/org/openstreetmap/josm/data/validation/Test.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/validation/Test.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/data/validation/Test.java	(revision 11608)
@@ -342,6 +342,5 @@
      */
     protected static final boolean isBuilding(OsmPrimitive p) {
-        String v = p.get("building");
-        return v != null && !"no".equals(v) && !"entrance".equals(v);
+        return p.hasTagDifferent("building", "no", "entrance");
     }
 
@@ -357,5 +356,5 @@
         Test test = (Test) obj;
         return Objects.equals(name, test.name) &&
-                Objects.equals(description, test.description);
+               Objects.equals(description, test.description);
     }
 }
Index: /trunk/src/org/openstreetmap/josm/data/validation/tests/Addresses.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/validation/tests/Addresses.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/data/validation/tests/Addresses.java	(revision 11608)
@@ -63,5 +63,5 @@
             // warning level only if several relations have different names, see #10945
             final String name = list.get(0).get("name");
-            if (name == null || SubclassFilteredCollection.filter(list, r -> name.equals(r.get("name"))).size() < list.size()) {
+            if (name == null || SubclassFilteredCollection.filter(list, r -> r.hasTag("name", name)).size() < list.size()) {
                 level = Severity.WARNING;
             } else {
@@ -147,5 +147,5 @@
                         street.add((Way) p);
                     }
-                    if (relationName != null && p.hasKey("name") && !relationName.equals(p.get("name"))) {
+                    if (relationName != null && p.hasTagDifferent("name", relationName)) {
                         if (wrongStreetNames.isEmpty()) {
                             wrongStreetNames.add(r);
Index: /trunk/src/org/openstreetmap/josm/data/validation/tests/Coastlines.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/validation/tests/Coastlines.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/data/validation/tests/Coastlines.java	(revision 11608)
@@ -251,5 +251,5 @@
 
     private static boolean isCoastline(OsmPrimitive osm) {
-        return osm instanceof Way && "coastline".equals(osm.get("natural"));
+        return osm instanceof Way && osm.hasTag("natural", "coastline");
     }
 
Index: /trunk/src/org/openstreetmap/josm/data/validation/tests/CrossingWays.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/validation/tests/CrossingWays.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/data/validation/tests/CrossingWays.java	(revision 11608)
@@ -241,5 +241,5 @@
 
     static boolean isHighway(OsmPrimitive w) {
-        return w.hasKey(HIGHWAY) && !w.hasTag(HIGHWAY, "rest_area", "services");
+        return w.hasTagDifferent(HIGHWAY, "rest_area", "services");
     }
 
Index: /trunk/src/org/openstreetmap/josm/data/validation/tests/Highways.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/validation/tests/Highways.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/data/validation/tests/Highways.java	(revision 11608)
@@ -92,6 +92,5 @@
     public void visit(Way w) {
         if (w.isUsable()) {
-            if (w.isClosed() && w.hasKey("highway") && CLASSIFIED_HIGHWAYS.contains(w.get("highway"))
-                    && w.hasKey("junction") && "roundabout".equals(w.get("junction"))) {
+            if (w.isClosed() && w.hasTag("highway", CLASSIFIED_HIGHWAYS) && w.hasTag("junction", "roundabout")) {
                 // TODO: find out how to handle splitted roundabouts (see #12841)
                 testWrongRoundabout(w);
@@ -131,7 +130,8 @@
                 if (list.size() > 2 || oneway1 == null || oneway2 == null || !oneway1 || !oneway2) {
                     // Error when the highway tags do not match
-                    if (!w.get("highway").equals(s)) {
+                    String value = w.get("highway");
+                    if (!value.equals(s)) {
                         errors.add(TestError.builder(this, Severity.WARNING, WRONG_ROUNDABOUT_HIGHWAY)
-                                .message(tr("Incorrect roundabout (highway: {0} instead of {1})", w.get("highway"), s))
+                                .message(tr("Incorrect roundabout (highway: {0} instead of {1})", value, s))
                                 .primitives(w)
                                 .fix(() -> new ChangePropertyCommand(w, "highway", s))
Index: /trunk/src/org/openstreetmap/josm/data/validation/tests/LongSegment.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/validation/tests/LongSegment.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/data/validation/tests/LongSegment.java	(revision 11608)
@@ -35,5 +35,5 @@
     @Override
     public void visit(Way w) {
-        if ("ferry".equals(w.get("route"))) {
+        if (w.hasTag("route", "ferry")) {
             return;
         }
Index: /trunk/src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java	(revision 11608)
@@ -175,5 +175,5 @@
     private void checkStyleConsistency(Relation r, Multipolygon polygon) {
         ElemStyles styles = MapPaintStyles.getStyles();
-        if (styles != null && !"boundary".equals(r.get("type"))) {
+        if (styles != null && !r.hasTag("type", "boundary")) {
             AreaElement area = ElemStyles.getAreaElemStyle(r, false);
             boolean areaStyle = area != null;
Index: /trunk/src/org/openstreetmap/josm/data/validation/tests/OverlappingWays.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/validation/tests/OverlappingWays.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/data/validation/tests/OverlappingWays.java	(revision 11608)
@@ -90,7 +90,7 @@
 
                 for (WaySegment ws : duplicated) {
-                    if (ws.way.get("highway") != null) {
+                    if (ws.way.hasKey("highway")) {
                         highway++;
-                    } else if (ws.way.get("railway") != null) {
+                    } else if (ws.way.hasKey("railway")) {
                         railway++;
                     }
@@ -107,8 +107,6 @@
                     currentWays.add(ws.way);
                 }
-                /* These ways not seen before
-                 * If two or more of the overlapping ways are
-                 * highways or railways mark a separate error
-                 */
+                // These ways not seen before
+                // If two or more of the overlapping ways are highways or railways mark a separate error
                 if ((highlight = seenWays.get(currentWays)) == null) {
                     String errortype;
Index: /trunk/src/org/openstreetmap/josm/data/validation/tests/PowerLines.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/validation/tests/PowerLines.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/data/validation/tests/PowerLines.java	(revision 11608)
@@ -165,6 +165,5 @@
      */
     private static boolean isPowerIn(OsmPrimitive p, Collection<String> values) {
-        String v = p.get("power");
-        return v != null && values != null && values.contains(v);
+        return p.hasTag("power", values);
     }
 
@@ -176,6 +175,5 @@
      */
     private static boolean isBuildingIn(OsmPrimitive p, Collection<String> values) {
-        String v = p.get("building");
-        return v != null && values != null && values.contains(v);
+        return p.hasTag("building", values);
     }
 }
Index: /trunk/src/org/openstreetmap/josm/data/validation/tests/TurnrestrictionTest.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/validation/tests/TurnrestrictionTest.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/data/validation/tests/TurnrestrictionTest.java	(revision 11608)
@@ -48,5 +48,5 @@
     @Override
     public void visit(Relation r) {
-        if (!"restriction".equals(r.get("type")))
+        if (!r.hasTag("type", "restriction"))
             return;
 
@@ -224,5 +224,5 @@
 
     private static boolean isFullOneway(Way w) {
-        return w.isOneway() != 0 && !"no".equals(w.get("oneway:bicycle"));
+        return w.isOneway() != 0 && !w.hasTag("oneway:bicycle", "no");
     }
 
Index: /trunk/src/org/openstreetmap/josm/data/validation/tests/UnconnectedWays.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/validation/tests/UnconnectedWays.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/data/validation/tests/UnconnectedWays.java	(revision 11608)
@@ -306,5 +306,5 @@
             this.isAbandoned = "abandoned".equals(railway) || w.isKeyTrue("disused");
             this.highway = (highway != null || railway != null) && !isAbandoned;
-            this.isBoundary = !this.highway && "administrative".equals(w.get("boundary"));
+            this.isBoundary = !this.highway && w.hasTag("boundary", "administrative");
             line = new Line2D.Double(n1.getEastNorth().east(), n1.getEastNorth().north(),
                     n2.getEastNorth().east(), n2.getEastNorth().north());
Index: /trunk/src/org/openstreetmap/josm/gui/DefaultNameFormatter.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/DefaultNameFormatter.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/gui/DefaultNameFormatter.java	(revision 11608)
@@ -169,6 +169,6 @@
                 }
                 if (n == null) {
-                    String s;
-                    if ((s = node.get("addr:housename")) != null) {
+                    String s = node.get("addr:housename");
+                    if (s != null) {
                         /* I18n: name of house as parameter */
                         n = tr("House {0}", s);
@@ -250,12 +250,12 @@
                 }
                 if (n == null) {
-                    n = (way.get("highway") != null) ? tr("highway") :
-                            (way.get("railway") != null) ? tr("railway") :
-                                (way.get("waterway") != null) ? tr("waterway") :
-                                        (way.get("landuse") != null) ? tr("landuse") : null;
+                    n = way.hasKey("highway") ? tr("highway") :
+                        way.hasKey("railway") ? tr("railway") :
+                        way.hasKey("waterway") ? tr("waterway") :
+                        way.hasKey("landuse") ? tr("landuse") : null;
                 }
                 if (n == null) {
-                    String s;
-                    if ((s = way.get("addr:housename")) != null) {
+                    String s = way.get("addr:housename");
+                    if (s != null) {
                         /* I18n: name of house as parameter */
                         n = tr("House {0}", s);
@@ -273,5 +273,7 @@
                     }
                 }
-                if (n == null && way.get("building") != null) n = tr("building");
+                if (n == null && way.hasKey("building")) {
+                    n = tr("building");
+                }
                 if (n == null || n.isEmpty()) {
                     n = String.valueOf(way.getId());
@@ -407,5 +409,5 @@
         String name = trc("Relation type", relation.get("type"));
         if (name == null) {
-            name = (relation.get("public_transport") != null) ? tr("public transport") : null;
+            name = relation.hasKey("public_transport") ? tr("public transport") : null;
         }
         if (name == null) {
@@ -573,12 +575,12 @@
         if (sb.length() == 0) {
             sb.append(
-                    (way.get("highway") != null) ? tr("highway") :
-                        (way.get("railway") != null) ? tr("railway") :
-                            (way.get("waterway") != null) ? tr("waterway") :
-                                (way.get("landuse") != null) ? tr("landuse") : ""
+                    way.hasKey("highway") ? tr("highway") :
+                    way.hasKey("railway") ? tr("railway") :
+                    way.hasKey("waterway") ? tr("waterway") :
+                    way.hasKey("landuse") ? tr("landuse") : ""
                     );
         }
 
-        int nodesNo = way.isClosed() ? way.getNumNodes() -1 : way.getNumNodes();
+        int nodesNo = way.isClosed() ? (way.getNumNodes() -1) : way.getNumNodes();
         String nodes = trn("{0} node", "{0} nodes", nodesNo, nodesNo);
         if (sb.length() == 0) {
@@ -587,5 +589,5 @@
         /* note: length == 0 should no longer happen, but leave the bracket code
            nevertheless, who knows what future brings */
-        sb.append((sb.length() > 0) ? " ("+nodes+')' : nodes);
+        sb.append((sb.length() > 0) ? (" ("+nodes+')') : nodes);
         decorateNameWithId(sb, way);
         return sb.toString();
@@ -595,6 +597,7 @@
     public String format(HistoryRelation relation) {
         StringBuilder sb = new StringBuilder();
-        if (relation.get("type") != null) {
-            sb.append(relation.get("type"));
+        String type = relation.get("type");
+        if (type != null) {
+            sb.append(type);
         } else {
             sb.append(tr("relation"));
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/sort/RelationSortUtils.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/sort/RelationSortUtils.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/sort/RelationSortUtils.java	(revision 11608)
@@ -29,5 +29,5 @@
 
     static Direction roundaboutType(Way w) {
-        if (w != null && "roundabout".equals(w.get("junction"))) {
+        if (w != null && w.hasTag("junction", "roundabout")) {
             int nodesCount = w.getNodesCount();
             if (nodesCount > 2 && nodesCount < 200) {
@@ -36,5 +36,5 @@
                 Node n3 = w.getNode(2);
                 if (n1 != null && n2 != null && n3 != null && w.isClosed()) {
-                    /** do some simple determinant / cross pruduct test on the first 3 nodes
+                    /** do some simple determinant / cross product test on the first 3 nodes
                         to see, if the roundabout goes clock wise or ccw */
                     EastNorth en1 = n1.getEastNorth();
Index: /trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java	(revision 11608)
@@ -605,7 +605,5 @@
         public boolean hasTag(String key) {
             HistoryOsmPrimitive primitive = getPointInTime(pointInTimeType);
-            if (primitive == null)
-                return false;
-            return primitive.hasTag(key);
+            return primitive != null && primitive.hasKey(key);
         }
 
@@ -620,7 +618,5 @@
             PointInTimeType opposite = pointInTimeType.opposite();
             HistoryOsmPrimitive primitive = getPointInTime(opposite);
-            if (primitive == null)
-                return false;
-            return primitive.hasTag(key);
+            return primitive != null && primitive.hasKey(key);
         }
 
@@ -636,7 +632,5 @@
             String value = getValue(key);
             String oppositeValue = getOppositeValue(key);
-            if (value == null || oppositeValue == null)
-                return false;
-            return value.equals(oppositeValue);
+            return value != null && value.equals(oppositeValue);
         }
 
Index: /trunk/src/org/openstreetmap/josm/gui/io/ChangesetCellRenderer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/io/ChangesetCellRenderer.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/gui/io/ChangesetCellRenderer.java	(revision 11608)
@@ -40,6 +40,7 @@
                     DateUtils.formatDateTime(cs.getCreatedAt(), DateFormat.SHORT, DateFormat.SHORT)).append("<br>");
         }
-        if (cs.get("comment") != null) {
-            sb.append("<strong>").append(tr("Changeset comment:")).append("</strong>").append(cs.get("comment")).append("<br>");
+        String comment = cs.get("comment");
+        if (comment != null) {
+            sb.append("<strong>").append(tr("Changeset comment:")).append("</strong>").append(comment).append("<br>");
         }
         return sb.toString();
@@ -59,6 +60,7 @@
             setIcon(icon);
             StringBuilder sb = new StringBuilder();
-            if (cs.get("comment") != null) {
-                sb.append(cs.getId()).append(" - ").append(cs.get("comment"));
+            String comment = cs.get("comment");
+            if (comment != null) {
+                sb.append(cs.getId()).append(" - ").append(comment);
             } else if (cs.get("name") != null) {
                 sb.append(cs.getId()).append(" - ").append(cs.get("name"));
Index: /trunk/src/org/openstreetmap/josm/gui/io/UploadParameterSummaryPanel.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/io/UploadParameterSummaryPanel.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/gui/io/UploadParameterSummaryPanel.java	(revision 11608)
@@ -8,4 +8,5 @@
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
+import java.util.Optional;
 
 import javax.swing.BorderFactory;
@@ -45,9 +46,7 @@
             msg.append(tr("Objects are uploaded to a <strong>new changeset</strong>."));
         } else {
-            String uploadComment = selectedChangeset.get("comment") == null ?
-                    "" : selectedChangeset.get("comment");
             msg.append(tr("Objects are uploaded to the <strong>open changeset</strong> {0} with upload comment ''{1}''.",
                     selectedChangeset.getId(),
-                    uploadComment
+                    Optional.ofNullable(selectedChangeset.get("comment")).orElse("")
             ));
         }
Index: /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 11608)
@@ -665,6 +665,7 @@
             Map<String, Object> trkAttr = new HashMap<>();
 
-            if (w.get("name") != null) {
-                trkAttr.put("name", w.get("name"));
+            String name = w.get("name");
+            if (name != null) {
+                trkAttr.put("name", name);
             }
 
Index: /trunk/src/org/openstreetmap/josm/gui/layer/gpx/ChooseTrackVisibilityAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/gpx/ChooseTrackVisibilityAction.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/gpx/ChooseTrackVisibilityAction.java	(revision 11608)
@@ -17,4 +17,5 @@
 import java.util.Comparator;
 import java.util.Map;
+import java.util.Optional;
 
 import javax.swing.AbstractAction;
@@ -111,9 +112,9 @@
         for (GpxTrack trk : layer.data.tracks) {
             Map<String, Object> attr = trk.getAttributes();
-            String name = (String) (attr.containsKey(GpxConstants.GPX_NAME) ? attr.get(GpxConstants.GPX_NAME) : "");
-            String desc = (String) (attr.containsKey(GpxConstants.GPX_DESC) ? attr.get(GpxConstants.GPX_DESC) : "");
+            String name = (String) Optional.ofNullable(attr.get(GpxConstants.GPX_NAME)).orElse("");
+            String desc = (String) Optional.ofNullable(attr.get(GpxConstants.GPX_DESC)).orElse("");
             String time = GpxLayer.getTimespanForTrack(trk);
             TrackLength length = new TrackLength(trk.length());
-            String url = (String) (attr.containsKey("url") ? attr.get("url") : "");
+            String url = (String) Optional.ofNullable(attr.get("url")).orElse("");
             tracks[i] = new Object[]{name, desc, time, length, url};
             i++;
Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java	(revision 11607)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java	(revision 11608)
@@ -388,5 +388,5 @@
                     addIfNotNull(sl, LineElement.createCasing(env));
                     addIfNotNull(sl, LineTextElement.create(env));
-                } else if ("restriction".equals(osm.get("type"))) {
+                } else if (osm.hasTag("type", "restriction")) {
                     addIfNotNull(sl, NodeElement.create(env));
                 }
