Index: src/org/openstreetmap/josm/data/validation/tests/TagChecker.java
===================================================================
--- src/org/openstreetmap/josm/data/validation/tests/TagChecker.java	(revision 11437)
+++ src/org/openstreetmap/josm/data/validation/tests/TagChecker.java	(working copy)
@@ -68,8 +68,8 @@
 
     /** Normalized keys: the key should be substituted by the value if the key was not found in presets */
     private static final Map<String, String> harmonizedKeys = new HashMap<>();
-    /** The spell check preset values */
-    private static volatile MultiMap<String, String> presetsValueData;
+    /** The spell check preset values which are not stored in TaggingPresets */
+    private static volatile MultiMap<String, String> additionalPresetsValueData;
     /** The TagChecker data */
     private static final List<CheckerData> checkerData = new ArrayList<>();
     private static final List<String> ignoreDataStartsWith = new ArrayList<>();
@@ -258,14 +258,14 @@
 
         Collection<TaggingPreset> presets = TaggingPresets.getTaggingPresets();
         if (!presets.isEmpty()) {
-            presetsValueData = new MultiMap<>();
+            additionalPresetsValueData = new MultiMap<>();
             for (String a : OsmPrimitive.getUninterestingKeys()) {
-                presetsValueData.putVoid(a);
+                additionalPresetsValueData.putVoid(a);
             }
             // TODO directionKeys are no longer in OsmPrimitive (search pattern is used instead)
             for (String a : Main.pref.getCollection(ValidatorPreference.PREFIX + ".knownkeys",
                     Arrays.asList(new String[]{"is_in", "int_ref", "fixme", "population"}))) {
-                presetsValueData.putVoid(a);
+                additionalPresetsValueData.putVoid(a);
             }
             for (TaggingPreset p : presets) {
                 for (TaggingPresetItem i : p.data) {
@@ -285,7 +285,6 @@
         Collection<String> values = ky.getValues();
         if (ky.key != null && values != null) {
             try {
-                presetsValueData.putAll(ky.key, values);
                 harmonizedKeys.put(harmonizeKey(ky.key), ky.key);
             } catch (NullPointerException e) {
                 Main.error(e, p+": Unable to initialize "+ky+'.');
@@ -308,6 +307,13 @@
         return false;
     }
 
+    private static Set<String> getPresetValues(String key) {
+        Set<String> res = TaggingPresets.getPresetValues(key);
+        if (res != null)
+            return res;
+        return additionalPresetsValueData.get(key);
+    }
+
     /**
      * Determines if the given key is in internal presets.
      * @param key key
@@ -315,7 +321,7 @@
      * @since 9023
      */
     public static boolean isKeyInPresets(String key) {
-        return presetsValueData.get(key) != null;
+        return getPresetValues(key) != null;
     }
 
     /**
@@ -326,7 +332,7 @@
      * @since 9023
      */
     public static boolean isTagInPresets(String key, String value) {
-        final Set<String> values = presetsValueData.get(key);
+        final Set<String> values = getPresetValues(key);
         return values != null && (values.isEmpty() || values.contains(value));
     }
 
@@ -465,7 +471,8 @@
                         .build());
                 withErrors.put(p, "HTML");
             }
-            if (checkValues && key != null && value != null && !value.isEmpty() && presetsValueData != null && !isTagIgnored(key, value)) {
+            if (checkValues && key != null && value != null && !value.isEmpty() && additionalPresetsValueData != null
+                    && !isTagIgnored(key, value)) {
                 if (!isKeyInPresets(key)) {
                     String prettifiedKey = harmonizeKey(key);
                     String fixedKey = harmonizedKeys.get(prettifiedKey);
@@ -490,7 +497,7 @@
                 } else if (!isTagInPresets(key, value)) {
                     // try to fix common typos and check again if value is still unknown
                     String fixedValue = harmonizeValue(prop.getValue());
-                    Map<String, String> possibleValues = getPossibleValues(presetsValueData.get(key));
+                    Map<String, String> possibleValues = getPossibleValues(getPresetValues(key));
                     if (possibleValues.containsKey(fixedValue)) {
                         final String newKey = possibleValues.get(fixedValue);
                         // misspelled preset value
Index: src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionManager.java
===================================================================
--- src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionManager.java	(revision 11437)
+++ src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionManager.java	(working copy)
@@ -14,7 +14,6 @@
 import java.util.Set;
 import java.util.function.Function;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Relation;
@@ -29,11 +28,7 @@
 import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
 import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
 import org.openstreetmap.josm.gui.tagging.presets.TaggingPreset;
-import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItem;
 import org.openstreetmap.josm.gui.tagging.presets.TaggingPresets;
-import org.openstreetmap.josm.gui.tagging.presets.items.CheckGroup;
-import org.openstreetmap.josm.gui.tagging.presets.items.KeyedItem;
-import org.openstreetmap.josm.gui.tagging.presets.items.Roles;
 import org.openstreetmap.josm.gui.tagging.presets.items.Roles.Role;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.MultiMap;
@@ -203,42 +198,6 @@
     }
 
     /**
-     * Initialize the cache for presets. This is done only once.
-     * @param presets Tagging presets to cache
-     */
-    public static void cachePresets(Collection<TaggingPreset> presets) {
-        for (final TaggingPreset p : presets) {
-            for (TaggingPresetItem item : p.data) {
-                cachePresetItem(p, item);
-            }
-        }
-    }
-
-    protected static void cachePresetItem(TaggingPreset p, TaggingPresetItem item) {
-        if (item instanceof KeyedItem) {
-            KeyedItem ki = (KeyedItem) item;
-            if (ki.key != null && ki.getValues() != null) {
-                try {
-                    PRESET_TAG_CACHE.putAll(ki.key, ki.getValues());
-                } catch (NullPointerException e) {
-                    Main.error(e, p + ": Unable to cache " + ki);
-                }
-            }
-        } else if (item instanceof Roles) {
-            Roles r = (Roles) item;
-            for (Role i : r.roles) {
-                if (i.key != null) {
-                    PRESET_ROLE_CACHE.add(i.key);
-                }
-            }
-        } else if (item instanceof CheckGroup) {
-            for (KeyedItem check : ((CheckGroup) item).checks) {
-                cachePresetItem(p, check);
-            }
-        }
-    }
-
-    /**
      * Remembers user input for the given key/value.
      * @param key Tag key
      * @param value Tag value
@@ -259,10 +218,6 @@
         return new ArrayList<>(getTagCache().keySet());
     }
 
-    protected List<String> getPresetKeys() {
-        return new ArrayList<>(PRESET_TAG_CACHE.keySet());
-    }
-
     protected Collection<String> getUserInputKeys() {
         List<String> keys = new ArrayList<>();
         for (UserInputTag tag : USER_INPUT_TAG_CACHE) {
@@ -285,10 +240,6 @@
         return new ArrayList<>(getTagCache().getValues(key));
     }
 
-    protected static List<String> getPresetValues(String key) {
-        return new ArrayList<>(PRESET_TAG_CACHE.getValues(key));
-    }
-
     protected static Collection<String> getUserInputValues(String key) {
         List<String> values = new ArrayList<>();
         for (UserInputTag tag : USER_INPUT_TAG_CACHE) {
@@ -316,7 +267,7 @@
      * @param list the list to populate
      */
     public void populateWithMemberRoles(AutoCompletionList list) {
-        list.add(PRESET_ROLE_CACHE, AutoCompletionItemPriority.IS_IN_STANDARD);
+        list.add(TaggingPresets.getPresetRoles(), AutoCompletionItemPriority.IS_IN_STANDARD);
         list.add(getRoleCache(), AutoCompletionItemPriority.IS_IN_DATASET);
     }
 
@@ -351,7 +302,7 @@
      * @param list the list to populate
      */
     public void populateWithKeys(AutoCompletionList list) {
-        list.add(getPresetKeys(), AutoCompletionItemPriority.IS_IN_STANDARD);
+        list.add(TaggingPresets.getPresetKeys(), AutoCompletionItemPriority.IS_IN_STANDARD);
         list.add(new AutoCompletionListItem("source", AutoCompletionItemPriority.IS_IN_STANDARD));
         list.add(getDataKeys(), AutoCompletionItemPriority.IS_IN_DATASET);
         list.addUserInput(getUserInputKeys());
@@ -377,7 +328,7 @@
      */
     public void populateWithTagValues(AutoCompletionList list, List<String> keys) {
         for (String key : keys) {
-            list.add(getPresetValues(key), AutoCompletionItemPriority.IS_IN_STANDARD);
+            list.add(TaggingPresets.getPresetValues(key), AutoCompletionItemPriority.IS_IN_STANDARD);
             list.add(getDataValues(key), AutoCompletionItemPriority.IS_IN_DATASET);
             list.addUserInput(getUserInputValues(key));
         }
Index: src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresets.java
===================================================================
--- src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresets.java	(revision 11437)
+++ src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresets.java	(working copy)
@@ -3,8 +3,11 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
 import javax.swing.JMenu;
 import javax.swing.JMenuItem;
@@ -13,7 +16,11 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.gui.MenuScroller;
-import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionManager;
+import org.openstreetmap.josm.gui.tagging.presets.items.CheckGroup;
+import org.openstreetmap.josm.gui.tagging.presets.items.KeyedItem;
+import org.openstreetmap.josm.gui.tagging.presets.items.Roles;
+import org.openstreetmap.josm.gui.tagging.presets.items.Roles.Role;
+import org.openstreetmap.josm.tools.MultiMap;
 import org.openstreetmap.josm.tools.SubclassFilteredCollection;
 
 /**
@@ -25,6 +32,11 @@
     /** The collection of tagging presets */
     private static final Collection<TaggingPreset> taggingPresets = new ArrayList<>();
 
+    /** cache for key/value pairs found in the preset */
+    private static final MultiMap<String, String> PRESET_TAG_CACHE = new MultiMap<>();
+    /** cache for roles found in the preset */
+    private static final Set<String> PRESET_ROLE_CACHE = new HashSet<>();
+
     /** The collection of listeners */
     private static final Collection<TaggingPresetListener> listeners = new ArrayList<>();
 
@@ -38,6 +50,7 @@
     public static void readFromPreferences() {
         taggingPresets.clear();
         taggingPresets.addAll(TaggingPresetReader.readFromPreferences(false, false));
+        cachePresets(taggingPresets);
     }
 
     /**
@@ -53,7 +66,6 @@
         if (taggingPresets.isEmpty()) {
             Main.main.menu.presetsMenu.setVisible(false);
         } else {
-            AutoCompletionManager.cachePresets(taggingPresets);
             Map<TaggingPresetMenu, JMenu> submenus = new HashMap<>();
             for (final TaggingPreset p : taggingPresets) {
                 JMenu m = p.group != null ? submenus.get(p.group) : Main.main.menu.presetsMenu;
@@ -87,14 +99,78 @@
     }
 
     /**
+     * Initialize the cache for presets. This is done only once.
+     * @param presets Tagging presets to cache
+     */
+    private static void cachePresets(Collection<TaggingPreset> presets) {
+        for (final TaggingPreset p : presets) {
+            for (TaggingPresetItem item : p.data) {
+                cachePresetItem(p, item);
+            }
+        }
+    }
+
+    private static void cachePresetItem(TaggingPreset p, TaggingPresetItem item) {
+        if (item instanceof KeyedItem) {
+            KeyedItem ki = (KeyedItem) item;
+            if (ki.key != null && ki.getValues() != null) {
+                try {
+                    PRESET_TAG_CACHE.putAll(ki.key, ki.getValues());
+                } catch (NullPointerException e) {
+                    Main.error(e, p + ": Unable to cache " + ki);
+                }
+            }
+        } else if (item instanceof Roles) {
+            Roles r = (Roles) item;
+            for (Role i : r.roles) {
+                if (i.key != null) {
+                    PRESET_ROLE_CACHE.add(i.key);
+                }
+            }
+        } else if (item instanceof CheckGroup) {
+            for (KeyedItem check : ((CheckGroup) item).checks) {
+                cachePresetItem(p, check);
+            }
+        }
+    }
+
+    /**
      * Replies a new collection containing all tagging presets.
      * @return a new collection containing all tagging presets. Empty if presets are not initialized (never null)
      */
     public static Collection<TaggingPreset> getTaggingPresets() {
-        return new ArrayList<>(taggingPresets);
+        return Collections.unmodifiableCollection(taggingPresets);
     }
 
     /**
+     * Replies a set of all roles in the tagging presets.
+     * @return a set of all roles in the tagging presets.
+     */
+    public static Set<String> getPresetRoles() {
+        return Collections.unmodifiableSet(PRESET_ROLE_CACHE);
+    }
+
+    /**
+     * Replies a set of all keys in the tagging presets.
+     * @return a set of all keys in the tagging presets.
+     */
+    public static Set<String> getPresetKeys() {
+        return Collections.unmodifiableSet(PRESET_TAG_CACHE.keySet());
+    }
+
+    /**
+     * Return set of values for a key in the tagging presets
+     * @param key the key
+     * @return set of values for a key in the tagging presets or null if none is found
+     */
+    public static Set<String> getPresetValues(String key) {
+        Set<String> values = PRESET_TAG_CACHE.get(key);
+        if (values != null)
+            return Collections.unmodifiableSet(values);
+        return null;
+    }
+
+    /**
      * Replies a new collection of all presets matching the parameters.
      *
      * @param t the preset types to include
