Index: /trunk/src/org/openstreetmap/josm/actions/ApiPreconditionChecker.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/ApiPreconditionChecker.java	(revision 1842)
+++ /trunk/src/org/openstreetmap/josm/actions/ApiPreconditionChecker.java	(revision 1843)
@@ -74,8 +74,5 @@
     private boolean checkMaxNodes(Collection<OsmPrimitive> add, long maxNodes) {
         for (OsmPrimitive osmPrimitive : add) {
-            if (osmPrimitive.keys == null) {
-                continue;
-            }
-            for (Entry<String,String> e : osmPrimitive.keys.entrySet()) {
+            for (Entry<String,String> e : osmPrimitive.entrySet()) {
                 if(e.getValue().length() > 255) {
                     if (osmPrimitive.deleted) {
Index: /trunk/src/org/openstreetmap/josm/actions/PasteTagsAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/PasteTagsAction.java	(revision 1842)
+++ /trunk/src/org/openstreetmap/josm/actions/PasteTagsAction.java	(revision 1843)
@@ -45,5 +45,5 @@
 
             for (String key : m.keySet()) {
-                clist.add(new ChangePropertyCommand(selectionSubset, key, osm.keys.get(key)));
+                clist.add(new ChangePropertyCommand(selectionSubset, key, osm.get(key)));
             }
         }
@@ -83,11 +83,7 @@
     private boolean containsSameKeysWithDifferentValues(Collection<? extends OsmPrimitive> osms) {
         Map<String,String> kvSeen = new HashMap<String,String>();
-        for (Iterator<? extends OsmPrimitive> it = osms.iterator(); it.hasNext();) {
-            OsmPrimitive osm = it.next();
-            if (osm.keys == null || osm.keys.isEmpty()) {
-                continue;
-            }
-            for (String key : osm.keys.keySet()) {
-                String value = osm.keys.get(key);
+        for (OsmPrimitive osm:osms) {
+            for (String key : osm.keySet()) {
+                String value = osm.get(key);
                 if (! kvSeen.containsKey(key)) {
                     kvSeen.put(key, value);
Index: /trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java	(revision 1842)
+++ /trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java	(revision 1843)
@@ -24,6 +24,4 @@
 import org.openstreetmap.josm.command.Command;
 import org.openstreetmap.josm.command.SequenceCommand;
-import org.openstreetmap.josm.data.SelectionChangedListener;
-import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -34,6 +32,4 @@
 import org.openstreetmap.josm.data.osm.visitor.Visitor;
 import org.openstreetmap.josm.gui.PrimitiveNameFormatter;
-import org.openstreetmap.josm.gui.layer.Layer;
-import org.openstreetmap.josm.gui.layer.Layer.LayerChangeListener;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -279,10 +275,9 @@
             }
             Relation c = null;
-            String type = "";
+            String type = r.get("type");
+            if (type == null) {
+                type = "";
+            }
             int i = 0;
-
-            if(r.keys != null) {
-                type = r.keys.get("type");
-            }
 
             for (RelationMember rm : r.members) {
Index: /trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java	(revision 1842)
+++ /trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java	(revision 1843)
@@ -94,5 +94,5 @@
 
             if (regexSearch) {
-                if (osm.keys == null)
+                if (!osm.hasKeys())
                     return false;
 
@@ -115,5 +115,5 @@
                 }
 
-                for (Entry<String, String> e : osm.keys.entrySet()) {
+                for (Entry<String, String> e : osm.entrySet()) {
                     String k = e.getKey();
                     String v = e.getValue();
@@ -223,5 +223,5 @@
         public boolean match(OsmPrimitive osm) throws ParseError {
 
-            if (osm.keys == null || osm.keys.isEmpty())
+            if (!osm.hasKeys())
                 return mode == Mode.NONE;
 
@@ -251,5 +251,5 @@
             case ANY_VALUE_REGEXP:
             case EXACT_REGEXP:
-                for (Entry<String, String> entry:osm.keys.entrySet()) {
+                for (Entry<String, String> entry:osm.entrySet()) {
                     if (keyPattern.matcher(entry.getKey()).matches()) {
                         if (mode == Mode.ANY_VALUE_REGEXP
@@ -260,5 +260,5 @@
                 return false;
             case MISSING_KEY_REGEXP:
-                for (String k:osm.keys.keySet()) {
+                for (String k:osm.keySet()) {
                     if (keyPattern.matcher(k).matches())
                         return false;
@@ -280,5 +280,5 @@
         public Any(String s) {this.s = s;}
         @Override public boolean match(OsmPrimitive osm) throws ParseError {
-            if (osm.keys == null)
+            if (!osm.hasKeys())
                 return s.equals("");
 
@@ -301,5 +301,5 @@
             // is not Java 1.5
             //search = java.text.Normalizer.normalize(search, java.text.Normalizer.Form.NFC);
-            for (Entry<String, String> e : osm.keys.entrySet()) {
+            for (Entry<String, String> e : osm.entrySet()) {
                 if (regexSearch) {
                     String key = e.getKey();
Index: /trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 1842)
+++ /trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 1843)
@@ -29,9 +29,4 @@
  */
 abstract public class OsmPrimitive implements Comparable<OsmPrimitive> {
-
-    /**
-     * The key/value list for this primitive.
-     */
-    public Map<String, String> keys;
 
     /* mappaint data */
@@ -219,4 +214,13 @@
     }
 
+    /*------------
+     * Keys handling
+     ------------*/
+
+    /**
+     * The key/value list for this primitive.
+     */
+    public Map<String, String> keys;
+
     /**
      * Set the given value to the given key
@@ -248,6 +252,11 @@
     }
 
-    public String getName() {
-        return null;
+    /**
+     * Added in revision 1843
+     * Please do not use in plug-ins until this version becomes JOSM tested
+     */
+    public final void removeAll() {
+        keys = null;
+        mappaintStyle = null;
     }
 
@@ -266,4 +275,21 @@
             return Collections.emptyList();
         return keys.keySet();
+    }
+
+    /**
+     * Added in revision 1843
+     * Please do not use in plug-ins until this version becomes JOSM tested
+     */
+    public final boolean hasKeys() {
+        return keys != null && !keys.isEmpty();
+    }
+
+
+
+
+
+
+    public String getName() {
+        return null;
     }
 
Index: /trunk/src/org/openstreetmap/josm/data/osm/visitor/MapPaintVisitor.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/visitor/MapPaintVisitor.java	(revision 1842)
+++ /trunk/src/org/openstreetmap/josm/data/osm/visitor/MapPaintVisitor.java	(revision 1843)
@@ -495,10 +495,10 @@
             return;
         }
-        else if (drawMultipolygon && r.keys != null && "multipolygon".equals(r.keys.get("type")))
+        else if (drawMultipolygon && "multipolygon".equals(r.get("type")))
         {
             if(drawMultipolygon(r))
               return;
         }
-        else if (drawRestriction && r.keys != null && "restriction".equals(r.keys.get("type")))
+        else if (drawRestriction && "restriction".equals(r.get("type")))
         {
             drawRestriction(r);
@@ -751,5 +751,5 @@
 
         if (nodeStyle == null) {
-            r.putError(tr("Style for restriction {0} not found.", r.keys.get("restriction")), true);
+            r.putError(tr("Style for restriction {0} not found.", r.get("restriction")), true);
             return;
         }
@@ -1112,7 +1112,7 @@
     protected String getNodeName(Node n) {
         String name = null;
-        if (n.keys != null) {
+        if (n.hasKeys()) {
             for (String rn : regionalNameOrder) {
-                name = n.keys.get(rn);
+                name = n.get(rn);
                 if (name != null) break;
             }
Index: /trunk/src/org/openstreetmap/josm/gui/conflict/tags/TagMergeItem.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/conflict/tags/TagMergeItem.java	(revision 1842)
+++ /trunk/src/org/openstreetmap/josm/gui/conflict/tags/TagMergeItem.java	(revision 1843)
@@ -3,6 +3,4 @@
 
 import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.util.HashMap;
 
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -56,12 +54,6 @@
         if (their == null) throw new IllegalArgumentException(tr("parameter '{0}' must not be null", "their"));
         this.key = key;
-        myTagValue = null;
-        if (my.keys != null && my.keys.containsKey(key)) {
-            myTagValue = my.keys.get(key);
-        }
-        theirTagValue = null;
-        if (their.keys != null && their.keys.containsKey(key)) {
-            theirTagValue = their.keys.get(key);
-        }
+        myTagValue = my.get(key);
+        theirTagValue = their.get(key);
     }
 
@@ -108,20 +100,14 @@
             throw new IllegalStateException(tr("cannot apply undecided tag merge item"));
         } else if (mergeDecision == MergeDecisionType.KEEP_THEIR) {
-            if (theirTagValue == null && primitive.keys != null) {
-                primitive.keys.remove(key);
+            if (theirTagValue == null) {
+                primitive.remove(key);
             } else if (theirTagValue != null) {
-                if (primitive.keys == null) {
-                    primitive.keys = new HashMap<String, String>();
-                }
-                primitive.keys.put(key, theirTagValue);
+                primitive.put(key, theirTagValue);
             }
         } else if (mergeDecision == MergeDecisionType.KEEP_MINE) {
-            if (myTagValue == null && primitive.keys != null) {
-                primitive.keys.remove(key);
+            if (myTagValue == null) {
+                primitive.remove(key);
             } else if (myTagValue != null) {
-                if (primitive.keys == null) {
-                    primitive.keys = new HashMap<String, String>();
-                }
-                primitive.keys.put(key, myTagValue);
+                primitive.put(key, myTagValue);
             }
         } else {
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java	(revision 1842)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java	(revision 1843)
@@ -240,16 +240,13 @@
                 HashMap<String, Vector<OsmPrimitive>> map=new HashMap<String, Vector<OsmPrimitive>>();
                 for (OsmPrimitive osm: sel) {
-                    if(osm.keys != null)
+                    String val=osm.get(key);
+                    if(val != null)
                     {
-                        String val=osm.keys.get(key);
-                        if(val != null)
-                        {
-                            if (map.containsKey(val)) {
-                                map.get(val).add(osm);
-                            } else {
-                                Vector<OsmPrimitive> v = new Vector<OsmPrimitive>();
-                                v.add(osm);
-                                map.put(val, v);
-                            }
+                        if (map.containsKey(val)) {
+                            map.get(val).add(osm);
+                        } else {
+                            Vector<OsmPrimitive> v = new Vector<OsmPrimitive>();
+                            v.add(osm);
+                            map.put(val, v);
                         }
                     }
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/TagEditorModel.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/TagEditorModel.java	(revision 1842)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/TagEditorModel.java	(revision 1843)
@@ -9,5 +9,4 @@
 import java.util.Collection;
 import java.util.Comparator;
-import java.util.HashMap;
 import java.util.List;
 import java.util.logging.Logger;
@@ -15,5 +14,4 @@
 import javax.swing.table.AbstractTableModel;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.command.ChangePropertyCommand;
 import org.openstreetmap.josm.command.Command;
@@ -24,6 +22,6 @@
 /**
  * TagEditorModel is a table model.
- * 
- * 
+ *
+ *
  * @author gubaer
  *
@@ -104,7 +102,7 @@
     /**
      * adds a tag to the model
-     * 
+     *
      * @param tag the tag. Must not be null.
-     * 
+     *
      * @exception IllegalArgumentException thrown, if tag is null
      */
@@ -129,11 +127,11 @@
     /**
      * adds a tag given by a name/value pair to the tag editor model.
-     * 
+     *
      * If there is no tag with name <code>name</name> yet, a new {@link TagModel} is created
      * and append to this model.
-     * 
+     *
      * If there is a tag with name <code>name</name>, <code>value</code> is merged to the list
      * of values for this tag.
-     * 
+     *
      * @param name the name; converted to "" if null
      * @param value the value; converted to "" if null
@@ -183,5 +181,5 @@
     /**
      * deletes the names of the tags given by tagIndices
-     * 
+     *
      * @param tagIndices a list of tag indices
      */
@@ -201,5 +199,5 @@
     /**
      * deletes the values of the tags given by tagIndices
-     * 
+     *
      * @param tagIndices the lit of tag indices
      */
@@ -219,5 +217,5 @@
     /**
      * deletes the tags given by tagIndices
-     * 
+     *
      * @param tagIndices the list of tag indices
      */
@@ -261,5 +259,5 @@
     /**
      * initializes the model with the tags of an OSM primitive
-     * 
+     *
      * @param primitive the OSM primitive
      */
@@ -278,14 +276,10 @@
     /**
      * applies the current state of the tag editor model to a primitive
-     * 
+     *
      * @param primitive the primitive
-     * 
+     *
      */
     public void applyToPrimitive(OsmPrimitive primitive) {
-        if (primitive.keys == null) {
-            primitive.keys = new HashMap<String, String>();
-        } else {
-            primitive.keys.clear();
-        }
+        primitive.removeAll();
         for (TagModel tag: tags) {
             // tag still holds an unchanged list of different values for the same key.
@@ -306,5 +300,5 @@
     /**
      * checks whether the tag model includes a tag with a given key
-     * 
+     *
      * @param key  the key
      * @return true, if the tag model includes the tag; false, otherwise
@@ -345,8 +339,5 @@
 
         for (OsmPrimitive primitive : primitives) {
-            if (primitive.keys == null) {
-                continue;
-            }
-            for (String oldkey : primitive.keys.keySet()) {
+            for (String oldkey : primitive.keySet()) {
                 if (!currentkeys.contains(oldkey)) {
                     ChangePropertyCommand deleteCommand =
@@ -367,5 +358,5 @@
     /**
      * replies the list of keys of the tags managed by this model
-     * 
+     *
      * @return the list of keys managed by this model
      */
@@ -397,5 +388,5 @@
      * updates the name of a tag and sets the dirty state to  true if
      * the new name is different from the old name.
-     * 
+     *
      * @param tag   the tag
      * @param newName  the new name
@@ -412,5 +403,5 @@
      * updates the value value of a tag and sets the dirty state to true if the
      * new name is different from the old name
-     * 
+     *
      * @param tag  the tag
      * @param newValue  the new value
@@ -426,5 +417,5 @@
     /**
      * replies true, if this model has been updated
-     * 
+     *
      * @return true, if this model has been updated
      */
Index: /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 1842)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 1843)
@@ -18,5 +18,4 @@
 import java.awt.TexturePaint;
 import java.awt.event.ActionEvent;
-import java.awt.event.KeyEvent;
 import java.awt.geom.Area;
 import java.awt.image.BufferedImage;
@@ -38,8 +37,5 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.actions.GpxExportAction;
 import org.openstreetmap.josm.actions.RenameLayerAction;
-import org.openstreetmap.josm.actions.SaveAction;
-import org.openstreetmap.josm.actions.SaveAsAction;
 import org.openstreetmap.josm.data.conflict.Conflict;
 import org.openstreetmap.josm.data.conflict.ConflictCollection;
@@ -67,5 +63,4 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
-import org.openstreetmap.josm.tools.Shortcut;
 
 /**
@@ -82,5 +77,5 @@
     /**
      * Replies a new unique name for a data layer
-     * 
+     *
      * @return a new unique name for a data layer
      */
@@ -497,6 +492,7 @@
                 wpt.setTime();
             }
-            if (n.keys != null && n.keys.containsKey("name")) {
-                wpt.attr.put("name", n.keys.get("name"));
+            String name = n.get("name");
+            if (name != null) {
+                wpt.attr.put("name", name);
             }
         }
Index: /trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java	(revision 1842)
+++ /trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java	(revision 1843)
@@ -4,14 +4,14 @@
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.Iterator;
-
+
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.OsmUtils;
 import org.openstreetmap.josm.data.osm.Way;
-import org.openstreetmap.josm.Main;
 
 public class ElemStyles
@@ -185,9 +185,9 @@
             {
                 boolean noclosed = o instanceof Way && !((Way)o).isClosed();
-                Iterator<String> iterator = o.keys.keySet().iterator();
+                Iterator<String> iterator = o.keySet().iterator();
                 while(iterator.hasNext())
                 {
                     String key = iterator.next();
-                    String val = o.keys.get(key);
+                    String val = o.get(key);
                     AreaElemStyle s = areas.get("n" + key + "=" + val);
                     if(s == null || (s.closed && noclosed))
Index: /trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java	(revision 1842)
+++ /trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java	(revision 1843)
@@ -106,7 +106,5 @@
                 returnValue.hadEmpty = true;
             }
-            if(s.keys != null && s.keys.size() > 0) {
-                returnValue.hadKeys = true;
-            }
+            returnValue.hadKeys = returnValue.hadKeys | s.hasKeys();
         }
         return returnValue;
@@ -220,5 +218,5 @@
                 {
                     for (OsmPrimitive s : sel)
-                        if(s.keys != null && s.keys.size() > 0) {
+                        if(s.hasKeys()) {
                             def = false;
                         }
@@ -381,7 +379,7 @@
 
             // no change if same as before
-            if (value.equals(originalValue) || (originalValue == null && (value == null || value.length() == 0))) return;
-
-            if (delete_if_empty && value != null && value.length() == 0) {
+            if (value.equals(originalValue) || (originalValue == null &&  value.length() == 0)) return;
+
+            if (delete_if_empty && value.length() == 0) {
                 value = null;
             }
Index: /trunk/src/org/openstreetmap/josm/io/OsmWriter.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/OsmWriter.java	(revision 1842)
+++ /trunk/src/org/openstreetmap/josm/io/OsmWriter.java	(revision 1843)
@@ -164,9 +164,9 @@
 
     private void addTags(OsmPrimitive osm, String tagname, boolean tagOpen) {
-        if (osm.keys != null) {
+        if (osm.hasKeys()) {
             if (tagOpen) {
                 out.println(">");
             }
-            for (Entry<String, String> e : osm.keys.entrySet()) {
+            for (Entry<String, String> e : osm.entrySet()) {
                 if ((osm instanceof Changeset) || !("created_by".equals(e.getKey())))
                     out.println("    <tag k='"+ XmlWriter.encode(e.getKey()) +
