Index: /trunk/src/org/openstreetmap/josm/data/preferences/EnumProperty.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/preferences/EnumProperty.java	(revision 9743)
+++ /trunk/src/org/openstreetmap/josm/data/preferences/EnumProperty.java	(revision 9743)
@@ -0,0 +1,34 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.preferences;
+
+import org.openstreetmap.josm.Main;
+
+/**
+ * A property containing an {@code Enum} value.
+ *
+ * @author András Kolesár
+ * @param <T> the {@code Enum} class
+ */
+public class EnumProperty<T extends Enum<T>> extends ParametrizedEnumProperty<T> {
+
+    protected final String key;
+
+    /**
+     * Constructs a new {@code EnumProperty}.
+     * @param key The property key
+     * @param enumClass The {@code Enum} class
+     * @param defaultValue The default value
+     */
+    public EnumProperty(String key, Class<T> enumClass, T defaultValue) {
+        super(enumClass, defaultValue);
+        this.key = key;
+        if (Main.pref != null) {
+            get();
+        }
+    }
+
+    @Override
+    protected String getKey(String... params) {
+        return key;
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/data/preferences/ParametrizedEnumProperty.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/preferences/ParametrizedEnumProperty.java	(revision 9742)
+++ /trunk/src/org/openstreetmap/josm/data/preferences/ParametrizedEnumProperty.java	(revision 9743)
@@ -6,13 +6,10 @@
 public abstract class ParametrizedEnumProperty<T extends Enum<T>> {
 
-    private final T defaultValue;
-    private final Class<T> enumClass;
+    protected final T defaultValue;
+    protected final Class<T> enumClass;
 
     public ParametrizedEnumProperty(Class<T> enumClass, T defaultValue) {
         this.defaultValue = defaultValue;
         this.enumClass = enumClass;
-        if (Main.pref != null) {
-            get();
-        }
     }
 
@@ -28,5 +25,9 @@
 
     protected T parse(String s) {
-        return Enum.valueOf(enumClass, s);
+        try {
+            return Enum.valueOf(enumClass, s);
+        } catch (IllegalArgumentException e) {
+            return defaultValue;
+        }
     }
 }
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/properties/TagEditHelper.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/properties/TagEditHelper.java	(revision 9742)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/properties/TagEditHelper.java	(revision 9743)
@@ -39,8 +39,10 @@
 import java.util.List;
 import java.util.Map;
+import java.util.TreeMap;
 
 import javax.swing.AbstractAction;
 import javax.swing.Action;
 import javax.swing.Box;
+import javax.swing.ButtonGroup;
 import javax.swing.DefaultListCellRenderer;
 import javax.swing.ImageIcon;
@@ -49,7 +51,9 @@
 import javax.swing.JLabel;
 import javax.swing.JList;
+import javax.swing.JMenu;
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JPopupMenu;
+import javax.swing.JRadioButtonMenuItem;
 import javax.swing.JTable;
 import javax.swing.KeyStroke;
@@ -66,4 +70,5 @@
 import org.openstreetmap.josm.data.osm.Tag;
 import org.openstreetmap.josm.data.preferences.BooleanProperty;
+import org.openstreetmap.josm.data.preferences.EnumProperty;
 import org.openstreetmap.josm.data.preferences.IntegerProperty;
 import org.openstreetmap.josm.gui.ExtendedDialog;
@@ -121,4 +126,34 @@
             DEFAULT_LRU_TAGS_NUMBER);
 
+    /**
+     * What to do with recent tags where keys already exist
+     */
+    private enum RecentExisting {
+        ENABLE,
+        DISABLE,
+        HIDE
+    }
+
+    /**
+     * Preference setting for popup menu item "Recent tags with existing key"
+     */
+    public static final EnumProperty<RecentExisting> PROPERTY_RECENT_EXISTING = new EnumProperty<>(
+        "properties.recently-added-tags-existing-key", RecentExisting.class, RecentExisting.DISABLE);
+
+    /**
+     * What to do after applying tag
+     */
+    private enum RefreshRecent {
+        NO,
+        STATUS,
+        REFRESH
+    }
+
+    /**
+     * Preference setting for popup menu item "Refresh recent tags list after applying tag"
+     */
+    public static final EnumProperty<RefreshRecent> PROPERTY_REFRESH_RECENT = new EnumProperty<>(
+        "properties.refresh-recently-added-tags", RefreshRecent.class, RefreshRecent.STATUS);
+
     // LRU cache for recently added tags (http://java-planet.blogspot.com/2005/08/how-to-set-up-simple-lru-cache-using.html)
     private final Map<Tag, Void> recentTags = new LinkedHashMap<Tag, Void>(MAX_LRU_TAGS_NUMBER+1, 1.1f, true) {
@@ -129,4 +164,13 @@
     };
 
+    // Copy of recently added tags, used to cache initial status
+    private List<Tag> tags;
+
+    /**
+     * Constructs a new {@code TagEditHelper}.
+     * @param tagTable
+     * @param propertyData
+     * @param valueCount
+     */
     public TagEditHelper(JTable tagTable, DefaultTableModel propertyData, Map<String, Map<String, Integer>> valueCount) {
         this.tagTable = tagTable;
@@ -135,8 +179,18 @@
     }
 
+    /**
+     * Finds the key from given row of tag editor.
+     * @param viewRow index of row
+     * @return key of tag
+     */
     public final String getDataKey(int viewRow) {
         return tagData.getValueAt(tagTable.convertRowIndexToModel(viewRow), 0).toString();
     }
 
+    /**
+     * Finds the values from given row of tag editor.
+     * @param viewRow index of row
+     * @return map of values and number of occurrences
+     */
     @SuppressWarnings("unchecked")
     public final Map<String, Integer> getDataValues(int viewRow) {
@@ -212,4 +266,7 @@
     }
 
+    /**
+     * Reset last changed key.
+     */
     public void resetChangedKey() {
         changedKey = null;
@@ -257,4 +314,11 @@
             Main.pref.putCollection("properties.recent-tags", c);
         }
+    }
+
+    /**
+     * Update cache of recent tags used for displaying tags.
+     */
+    private void cacheRecentTags() {
+        tags = new LinkedList<>(recentTags.keySet());
     }
 
@@ -573,4 +637,5 @@
         private final List<JosmAction> recentTagsActions = new ArrayList<>();
         protected final transient FocusAdapter focus;
+        private JPanel mainPanel;
         private JPanel recentTagsPanel;
 
@@ -584,5 +649,5 @@
             configureContextsensitiveHelp("/Dialog/AddValue", true /* show help button */);
 
-            final JPanel mainPanel = new JPanel(new GridBagLayout());
+            mainPanel = new JPanel(new GridBagLayout());
             keys = new AutoCompletingComboBox();
             values = new AutoCompletingComboBox();
@@ -641,9 +706,11 @@
                     public void actionPerformed(ActionEvent e) {
                         performTagAdding();
+                        refreshRecentTags();
                         selectKeysComboBox();
                     }
                 });
 
-            suggestRecentlyAddedTags(mainPanel);
+            cacheRecentTags();
+            suggestRecentlyAddedTags();
 
             mainPanel.add(Box.createVerticalGlue(), GBC.eop().fill());
@@ -656,7 +723,11 @@
                 public void actionPerformed(ActionEvent e) {
                     selectNumberOfTags();
-                    suggestRecentlyAddedTags(mainPanel);
+                    suggestRecentlyAddedTags();
                 }
             });
+
+            popupMenu.add(buildMenuRecentExisting());
+            popupMenu.add(buildMenuRefreshRecent());
+
             JCheckBoxMenuItem rememberLastTags = new JCheckBoxMenuItem(
                 new AbstractAction(tr("Remember last used tags after a restart")) {
@@ -673,4 +744,47 @@
         }
 
+        private JMenu buildMenuRecentExisting() {
+            JMenu menu = new JMenu(tr("Recent tags with existing key"));
+            TreeMap<RecentExisting, String> radios = new TreeMap<>();
+            radios.put(RecentExisting.ENABLE, tr("Enable"));
+            radios.put(RecentExisting.DISABLE, tr("Disable"));
+            radios.put(RecentExisting.HIDE, tr("Hide"));
+            ButtonGroup buttonGroup = new ButtonGroup();
+            for (final Map.Entry<RecentExisting, String> entry : radios.entrySet()) {
+                JRadioButtonMenuItem radio = new JRadioButtonMenuItem(new AbstractAction(entry.getValue()) {
+                    @Override
+                    public void actionPerformed(ActionEvent e) {
+                        PROPERTY_RECENT_EXISTING.put(entry.getKey());
+                        suggestRecentlyAddedTags();
+                    }
+                });
+                buttonGroup.add(radio);
+                radio.setSelected(PROPERTY_RECENT_EXISTING.get() == entry.getKey());
+                menu.add(radio);
+            }
+            return menu;
+        }
+
+        private JMenu buildMenuRefreshRecent() {
+            JMenu menu = new JMenu(tr("Refresh recent tags list after applying tag"));
+            TreeMap<RefreshRecent, String> radios = new TreeMap<>();
+            radios.put(RefreshRecent.NO, tr("No refresh"));
+            radios.put(RefreshRecent.STATUS, tr("Refresh tag status only (enabled / disabled)"));
+            radios.put(RefreshRecent.REFRESH, tr("Refresh tag status and list of recently added tags"));
+            ButtonGroup buttonGroup = new ButtonGroup();
+            for (final Map.Entry<RefreshRecent, String> entry : radios.entrySet()) {
+                JRadioButtonMenuItem radio = new JRadioButtonMenuItem(new AbstractAction(entry.getValue()) {
+                    @Override
+                    public void actionPerformed(ActionEvent e) {
+                        PROPERTY_REFRESH_RECENT.put(entry.getKey());
+                    }
+                });
+                buttonGroup.add(radio);
+                radio.setSelected(PROPERTY_REFRESH_RECENT.get() == entry.getKey());
+                menu.add(radio);
+            }
+            return menu;
+        }
+
         @Override
         public void setContentPane(Container contentPane) {
@@ -713,14 +827,13 @@
         }
 
-        protected void suggestRecentlyAddedTags(JPanel mainPanel) {
-
+        protected void suggestRecentlyAddedTags() {
             if (recentTagsPanel == null) {
                 recentTagsPanel = new JPanel(new GridBagLayout());
-                suggestRecentlyAddedTags();
+                buildRecentTagsPanel();
                 mainPanel.add(recentTagsPanel, GBC.eol().fill(GBC.HORIZONTAL));
             } else {
                 Dimension panelOldSize = recentTagsPanel.getPreferredSize();
                 recentTagsPanel.removeAll();
-                suggestRecentlyAddedTags();
+                buildRecentTagsPanel();
                 Dimension panelNewSize = recentTagsPanel.getPreferredSize();
                 Dimension dialogOldSize = getMinimumSize();
@@ -734,5 +847,5 @@
         }
 
-        protected void suggestRecentlyAddedTags() {
+        protected void buildRecentTagsPanel() {
             final int tagsToShow = Math.min(PROPERTY_RECENT_TAGS_NUMBER.get(), MAX_LRU_TAGS_NUMBER);
             if (!(tagsToShow > 0 && !recentTags.isEmpty()))
@@ -740,5 +853,6 @@
             recentTagsPanel.add(new JLabel(tr("Recently added tags")), GBC.eol());
 
-            int count = 1;
+            int count = 0;
+            destroyActions();
             // We store the maximum number of recent tags to allow dynamic change of number of tags shown in the preferences.
             // This implies to iterate in descending order, as the oldest elements will only be removed after we reach the maximum
@@ -746,7 +860,10 @@
             // However, as Set does not allow to iterate in descending order, we need to copy its elements into a List we can access
             // in reverse order.
-            List<Tag> tags = new LinkedList<>(recentTags.keySet());
-            for (int i = tags.size()-1; i >= 0 && count <= tagsToShow; i--, count++) {
+            for (int i = tags.size()-1; i >= 0 && count < tagsToShow; i--) {
                 final Tag t = tags.get(i);
+                boolean keyExists = keyExists(t);
+                if (keyExists && PROPERTY_RECENT_EXISTING.get() == RecentExisting.HIDE)
+                    continue;
+                count++;
                 // Create action for reusing the tag, with keyboard shortcut
                 /* POSSIBLE SHORTCUTS: 1,2,3,4,5,6,7,8,9,0=10 */
@@ -773,4 +890,5 @@
                         action.actionPerformed(null);
                         performTagAdding();
+                        refreshRecentTags();
                         selectKeysComboBox();
                     }
@@ -778,5 +896,7 @@
                 recentTagsActions.add(action);
                 recentTagsActions.add(actionShift);
-                disableTagIfNeeded(t, action);
+                if (keyExists && PROPERTY_RECENT_EXISTING.get() == RecentExisting.DISABLE) {
+                    action.setEnabled(false);
+                }
                 // Find and display icon
                 ImageIcon icon = MapPaintStyles.getNodeIcon(t, false); // Filters deprecated icon
@@ -823,12 +943,12 @@
                         public void mouseClicked(MouseEvent e) {
                             action.actionPerformed(null);
-                            // add tags and close window on double-click
-                            if (e.getClickCount() > 1) {
+                            if (e.isShiftDown()) {
+                                // add tags on Shift-Click
+                                performTagAdding();
+                                refreshRecentTags();
+                                selectKeysComboBox();
+                            } else if (e.getClickCount() > 1) {
+                                // add tags and close window on double-click
                                 buttonAction(0, null); // emulate OK click and close the dialog
-                            }
-                            // add tags on Shift-Click
-                            if (e.isShiftDown()) {
-                                performTagAdding();
-                                selectKeysComboBox();
                             }
                         }
@@ -844,4 +964,8 @@
                 tagPanel.add(tagLabel);
                 recentTagsPanel.add(tagPanel, GBC.eol().fill(GBC.HORIZONTAL));
+            }
+            // Clear label if no tags were added
+            if (count == 0) {
+                recentTagsPanel.removeAll();
             }
         }
@@ -873,4 +997,5 @@
             lastAddValue = value;
             recentTags.put(new Tag(key, value), null);
+            valueCount.put(key, new TreeMap<String, Integer>());
             AutoCompletionManager.rememberUserInput(key, value, false);
             commandCount++;
@@ -889,12 +1014,12 @@
         }
 
-        private void disableTagIfNeeded(final Tag t, final JosmAction action) {
-            // Disable action if its key is already set on the object (the key being absent from the keys list for this reason
-            // performing this action leads to autocomplete to the next key (see #7671 comments)
-            for (int j = 0; j < tagData.getRowCount(); ++j) {
-                if (t.getKey().equals(getDataKey(j))) {
-                    action.setEnabled(false);
-                    break;
-                }
+        private boolean keyExists(final Tag t) {
+            return valueCount.containsKey(t.getKey());
+        }
+
+        private void refreshRecentTags() {
+            switch (PROPERTY_REFRESH_RECENT.get()) {
+                case REFRESH: cacheRecentTags(); // break missing intentionally
+                case STATUS: suggestRecentlyAddedTags();
             }
         }
