Index: /trunk/src/org/openstreetmap/josm/actions/OpenFileAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/OpenFileAction.java	(revision 2945)
+++ /trunk/src/org/openstreetmap/josm/actions/OpenFileAction.java	(revision 2946)
@@ -135,5 +135,5 @@
                         for (FileImporter importer : ExtensionFileFilter.importers) {
                             if (importer.acceptFile(f)) {
-                                map.add(importer, f);
+                                map.put(importer, f);
                                 continue FILES;
                             }
@@ -146,5 +146,5 @@
                 for (FileImporter importer : ims) {
                     //System.err.println("Using "+importer.getClass().getName());
-                    List<File> files = map.get(importer);
+                    List<File> files = new ArrayList<File>(map.get(importer));
                     //System.err.println("for files: "+files);
                     importData(importer, files);
Index: /trunk/src/org/openstreetmap/josm/gui/preferences/TaggingPresetPreference.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/preferences/TaggingPresetPreference.java	(revision 2945)
+++ /trunk/src/org/openstreetmap/josm/gui/preferences/TaggingPresetPreference.java	(revision 2946)
@@ -21,4 +21,5 @@
 import org.openstreetmap.josm.gui.tagging.TaggingPresetMenu;
 import org.openstreetmap.josm.gui.tagging.TaggingPresetSeparator;
+import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionCache;
 import org.openstreetmap.josm.tools.GBC;
 
@@ -87,4 +88,5 @@
         else
         {
+            AutoCompletionCache.cachePresets(taggingPresets);
             HashMap<TaggingPresetMenu,JMenu> submenus = new HashMap<TaggingPresetMenu,JMenu>();
             for (final TaggingPreset p : taggingPresets)
Index: /trunk/src/org/openstreetmap/josm/gui/tagging/TagCellEditor.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/tagging/TagCellEditor.java	(revision 2945)
+++ /trunk/src/org/openstreetmap/josm/gui/tagging/TagCellEditor.java	(revision 2946)
@@ -62,9 +62,5 @@
         // add the list of keys in the current data set
         //
-        for (String key : acCache.getKeys()) {
-            autoCompletionList.add(
-                    new AutoCompletionListItem(key, AutoCompletionItemPritority.IS_IN_DATASET)
-            );
-        }
+        acCache.populateWithKeys(autoCompletionList, true);
 
         // remove the keys already present in the current tag model
@@ -91,10 +87,5 @@
             return;
         }
-        autoCompletionList.clear();
-        for (String value : acCache.getValues(forKey)) {
-            autoCompletionList.add(
-                    new AutoCompletionListItem(value, AutoCompletionItemPritority.IS_IN_DATASET)
-            );
-        }
+        acCache.populateWithTagValues(autoCompletionList, forKey, false);
     }
 
Index: /trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java	(revision 2945)
+++ /trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java	(revision 2946)
@@ -82,6 +82,5 @@
             if (layer == null) return;
             AutoCompletionList list  = new AutoCompletionList();
-            List<String> values = AutoCompletionCache.getCacheForLayer(Main.main.getEditLayer()).getValues(key);
-            list.add(values,AutoCompletionItemPritority.IS_IN_DATASET);
+            AutoCompletionCache.getCacheForLayer(Main.main.getEditLayer()).populateWithTagValues(list, key, false);
             field.setAutoCompletionList(list);
         }
Index: /trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionCache.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionCache.java	(revision 2945)
+++ /trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionCache.java	(revision 2946)
@@ -10,4 +10,5 @@
 
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.OsmUtils;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.RelationMember;
@@ -15,4 +16,6 @@
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.gui.tagging.TaggingPreset;
+import org.openstreetmap.josm.tools.MultiMap;
 
 /**
@@ -67,10 +70,12 @@
     }
 
-    /** the cached tags give by a tag key and a list of values for this tag*/
-    private HashMap<String, Set<String>> tagCache;
+    /** the cached tags given by a tag key and a list of values for this tag */
+    private MultiMap<String, String> tagCache;
+    /**  the layer this cache is built for */
+    private OsmDataLayer layer;
+    /** the same as tagCache but for the preset keys and values */
+    private static MultiMap<String, String> presetTagCache = new MultiMap<String, String>();
     /** the cached list of member roles */
     private  Set<String> roleCache;
-    /**  the layer this cache is built for */
-    private OsmDataLayer layer;
 
     /**
@@ -78,5 +83,5 @@
      */
     public AutoCompletionCache(OsmDataLayer layer) {
-        tagCache = new HashMap<String, Set<String>>();
+        tagCache = new MultiMap<String, String>();
         roleCache = new HashSet<String>();
         this.layer = layer;
@@ -85,26 +90,4 @@
     public AutoCompletionCache() {
         this(null);
-    }
-
-    /**
-     * make sure, <code>key</code> is in the cache
-     *
-     * @param key  the key
-     */
-    protected void cacheKey(String key) {
-        if (tagCache.containsKey(key))
-            return;
-        tagCache.put(key, new HashSet<String>());
-    }
-
-    /**
-     * make sure, value is one of the auto completion values allowed for key
-     *
-     * @param key the key
-     * @param value the value
-     */
-    protected void cacheValue(String key, String value) {
-        cacheKey(key);
-        tagCache.get(key).add(value);
     }
 
@@ -118,5 +101,5 @@
         for (String key: primitive.keySet()) {
             String value = primitive.get(key);
-            cacheValue(key, value);
+            tagCache.put(key, value);
         }
     }
@@ -141,5 +124,5 @@
      */
     public void initFromDataSet() {
-        tagCache = new HashMap<String, Set<String>>();
+        tagCache = new MultiMap<String, String>();
         if (layer == null)
             return;
@@ -157,10 +140,43 @@
 
     /**
+     * Initialize the cache for presets. This is done only once.
+     */
+    public static void cachePresets(Collection<TaggingPreset> presets) {
+        for (final TaggingPreset p : presets) {
+            for (TaggingPreset.Item item : p.data) {
+                if (item instanceof TaggingPreset.Check) {
+                    TaggingPreset.Check ch = (TaggingPreset.Check) item;
+                    presetTagCache.put(ch.key, OsmUtils.falseval);
+                    presetTagCache.put(ch.key, OsmUtils.trueval);
+                } else if (item instanceof TaggingPreset.Combo) {
+                    TaggingPreset.Combo co = (TaggingPreset.Combo) item;
+                    for (String value : co.values.split(",")) {
+                        presetTagCache.put(co.key, value);
+                    }
+                } else if (item instanceof TaggingPreset.Key) {
+                    TaggingPreset.Key ky = (TaggingPreset.Key) item;
+                    presetTagCache.put(ky.key, ky.value);
+                } else if (item instanceof TaggingPreset.Text) {
+                    TaggingPreset.Text tt = (TaggingPreset.Text) item;
+                    presetTagCache.putVoid(tt.key);
+                    if (tt.default_ != null && !tt.default_.equals("")) {
+                        presetTagCache.put(tt.key, tt.default_);
+                    }
+                }
+            }
+        }
+    }
+    
+    /**
      * replies the keys held by the cache
      *
      * @return the list of keys held by the cache
      */
-    public List<String> getKeys() {
+    protected List<String> getDataKeys() {
         return new ArrayList<String>(tagCache.keySet());
+    }
+
+    protected List<String> getPresetKeys() {
+        return new ArrayList<String>(presetTagCache.keySet());
     }
 
@@ -172,8 +188,10 @@
      * @return the list of auto completion values
      */
-    public List<String> getValues(String key) {
-        if (!tagCache.containsKey(key))
-            return new ArrayList<String>();
-        return new ArrayList<String>(tagCache.get(key));
+    protected List<String> getDataValues(String key) {
+        return new ArrayList<String>(tagCache.getValues(key));
+    }
+
+    protected static List<String> getPresetValues(String key) {
+        return new ArrayList<String>(presetTagCache.getValues(key));
     }
 
@@ -211,5 +229,6 @@
             list.clear();
         }
-        list.add(getValues(key), AutoCompletionItemPritority.IS_IN_DATASET);
+        list.add(getDataValues(key), AutoCompletionItemPritority.IS_IN_DATASET);
+        list.add(getPresetValues(key), AutoCompletionItemPritority.IS_IN_STANDARD);
     }
 
@@ -226,5 +245,6 @@
             list.clear();
         }
-        list.add(tagCache.keySet(), AutoCompletionItemPritority.IS_IN_DATASET);
+        list.add(getDataKeys(), AutoCompletionItemPritority.IS_IN_DATASET);
+        list.add(getPresetKeys(), AutoCompletionItemPritority.IS_IN_STANDARD);
     }
 }
Index: /trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionItemPritority.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionItemPritority.java	(revision 2945)
+++ /trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionItemPritority.java	(revision 2946)
@@ -4,19 +4,27 @@
 public enum AutoCompletionItemPritority implements Comparable<AutoCompletionItemPritority> {
 
-    /** indicates that a value is in the current selection */
+    /** Indicates that a value is in the current selection. */
     IS_IN_SELECTION,
 
-    /** indicates that this is a standard value, i.e. a standard tag name
-     *  or a standard value for a given tag name
+    /**
+     * Indicates, that the value is standard and it is found in the data.
+     * This has higher priority than some arbitrary standard value that is
+     * usually not used by the user.
+     */
+    IS_IN_STANDARD_AND_IN_DATASET,
+
+    /**
+     * Indicates that this is a standard value, i.e. a standard tag name
+     * or a standard value for a given tag name (from the presets).
      */
     IS_IN_STANDARD,
 
     /**
-     * indicates that this is an arbitrary value from the data set, i.e.
-     * the value of a tag name=xxx
+     * Indicates that this is an arbitrary value from the data set, i.e.
+     * the value of a tag name=*.
      */
     IS_IN_DATASET,
 
-    /** unknown priority. This is the lowest priority. */
+    /** Unknown priority. This is the lowest priority. */
     UNKNOWN
 }
Index: /trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionList.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionList.java	(revision 2945)
+++ /trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionList.java	(revision 2946)
@@ -157,7 +157,16 @@
         } else {
             // new item already exists. Update priority if necessary
-            //
-            if (toadd.getPriority().compareTo(item.getPriority()) < 0) {
-                item.setPriority(toadd.getPriority());
+
+            // If it is both in the dataset and in the presets, update the priority.
+            final AutoCompletionItemPritority IS_IN_DATASET = AutoCompletionItemPritority.IS_IN_DATASET;
+            final AutoCompletionItemPritority IS_IN_STANDARD = AutoCompletionItemPritority.IS_IN_STANDARD;
+            if ((toadd.getPriority() == IS_IN_STANDARD && item.getPriority() == IS_IN_DATASET) ||
+                (toadd.getPriority() == IS_IN_DATASET && item.getPriority() == IS_IN_STANDARD)) {
+
+                item.setPriority(AutoCompletionItemPritority.IS_IN_STANDARD_AND_IN_DATASET);
+            } else {
+                if (toadd.getPriority().compareTo(item.getPriority()) < 0) {
+                    item.setPriority(toadd.getPriority());
+                }
             }
         }
Index: /trunk/src/org/openstreetmap/josm/tools/MultiMap.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/tools/MultiMap.java	(revision 2945)
+++ /trunk/src/org/openstreetmap/josm/tools/MultiMap.java	(revision 2946)
@@ -2,19 +2,41 @@
 package org.openstreetmap.josm.tools;
 
-import java.util.ArrayList;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.HashMap;
 
 /**
- * Maps keys to a list of values. Partial implementation. Extend if you need more!
+ * Maps keys to ordered sets of values.
  */
-public class MultiMap<A, B> extends HashMap<A, List<B>> {
-    public void add(A key, B value) {
-        List<B> vals = get(key);
+public class MultiMap<A, B> extends HashMap<A, LinkedHashSet<B>> {
+    /**
+     * Map a key to a value. Can be called multiple times with the same key, but different value.
+     */
+    public void put(A key, B value) {
+        LinkedHashSet<B> vals = get(key);
         if (vals == null) {
-            vals = new ArrayList<B>();
+            vals = new LinkedHashSet<B>();
             put(key, vals);
         }
         vals.add(value);
     }
+    
+    /**
+     * Put a key that maps to nothing.
+     */
+    public void putVoid(A key) {
+        if (containsKey(key))
+            return;
+        put(key, new LinkedHashSet<B>());
+    }
+
+    /**
+     * Returns a list of values for the given key
+     * or an empty list, if it maps to nothing.
+     */
+    public LinkedHashSet<B> getValues(A key) {
+        if (!containsKey(key))
+            return new LinkedHashSet<B>();
+        return get(key);
+    }
 }
