Index: trunk/src/org/openstreetmap/josm/gui/dialogs/properties/TagEditHelper.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/properties/TagEditHelper.java	(revision 7724)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/properties/TagEditHelper.java	(revision 7725)
@@ -371,4 +371,5 @@
             if (key.equals(newkey) || value == null) {
                 Main.main.undoRedo.add(new ChangePropertyCommand(sel, newkey, value));
+                AutoCompletionManager.rememberUserInput(newkey, value, true);
             } else {
                 for (OsmPrimitive osm: sel) {
@@ -401,4 +402,5 @@
                 } else {
                     commands.add(new ChangePropertyCommand(sel, newkey, value));
+                    AutoCompletionManager.rememberUserInput(newkey, value, false);
                 }
                 Main.main.undoRedo.add(new SequenceCommand(
@@ -771,4 +773,5 @@
             lastAddValue = value;
             recentTags.put(new Tag(key, value), null);
+            AutoCompletionManager.rememberUserInput(key, value, false);
             commandCount++;
             Main.main.undoRedo.add(new ChangePropertyCommand(sel, key, value));
Index: trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPresetItems.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPresetItems.java	(revision 7724)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPresetItems.java	(revision 7725)
@@ -54,4 +54,5 @@
 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionItemPriority;
 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionList;
+import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionManager;
 import org.openstreetmap.josm.gui.widgets.JosmComboBox;
 import org.openstreetmap.josm.gui.widgets.JosmTextField;
@@ -767,4 +768,5 @@
 
             changedTags.add(new Tag(key, v));
+            AutoCompletionManager.rememberUserInput(key, v, true);
         }
 
Index: trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionItemPriority.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionItemPriority.java	(revision 7724)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionItemPriority.java	(revision 7725)
@@ -37,12 +37,31 @@
     public static final AutoCompletionItemPriority UNKNOWN = new AutoCompletionItemPriority(false, false, false);
 
+    private final static int NO_USER_INPUT = Integer.MAX_VALUE;
+
+    private final int userInput;
     private final boolean inDataSet;
     private final boolean inStandard;
     private final boolean selected;
+    
 
-    public AutoCompletionItemPriority(boolean inDataSet, boolean inStandard, boolean selected) {
+    /**
+     * Create new AutoCompletionItemPriority object.
+     * 
+     * @param inDataSet true, if the item is found in the currently active data layer
+     * @param inStandard true, if the item is a standard tag, e.g. from the presets.
+     * @param selected true, if it is found on an object that is currently selected
+     * @param userInput null, if the user hasn't entered this tag so far. A number when
+     * the tag key / value has been entered by the user before. A lower number means
+     * this happened more recently and beats a higher number in priority.
+     */
+    public AutoCompletionItemPriority(boolean inDataSet, boolean inStandard, boolean selected, Integer userInput) {
         this.inDataSet = inDataSet;
         this.inStandard = inStandard;
         this.selected = selected;
+        this.userInput = userInput == null ? NO_USER_INPUT : userInput;
+    }
+
+    public AutoCompletionItemPriority(boolean inDataSet, boolean inStandard, boolean selected) {
+        this(inDataSet, inStandard, selected, NO_USER_INPUT);
     }
 
@@ -59,4 +78,8 @@
     }
 
+    public Integer getUserInput() {
+        return userInput == NO_USER_INPUT ? null : userInput;
+    }
+    
     /**
      * Imposes an ordering on the priorities.
@@ -65,4 +88,7 @@
     @Override
     public int compareTo(AutoCompletionItemPriority other) {
+        int ui = -Integer.compare(userInput, other.userInput);
+        if (ui != 0) return ui;
+
         int sel = Boolean.valueOf(selected).compareTo(other.selected);
         if (sel != 0) return sel;
@@ -85,9 +111,11 @@
                 inDataSet || other.inDataSet,
                 inStandard || other.inStandard,
-                selected || other.selected);
+                selected || other.selected,
+                Math.min(userInput, other.userInput));
     }
 
     @Override public String toString() {
-        return String.format("<Priority; inDataSet: %b, inStandard: %b, selected: %b>", inDataSet, inStandard, selected);
+        return String.format("<Priority; userInput: %s, inDataSet: %b, inStandard: %b, selected: %b>", 
+                userInput == NO_USER_INPUT ? "no" : Integer.toString(userInput), inDataSet, inStandard, selected);
     }
 }
Index: trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionList.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionList.java	(revision 7724)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionList.java	(revision 7725)
@@ -148,4 +148,19 @@
         filter();
     }
+    
+    public void addUserInput(Collection<String> values) {
+        if (values == null) return;
+        int i = 0;
+        for (String value: values) {
+            if (value == null) {
+                continue;
+            }
+            AutoCompletionListItem item = new AutoCompletionListItem(value, new AutoCompletionItemPriority(false, false, false, i));
+            appendOrUpdatePriority(item);
+            i++;
+        }
+        sort();
+        filter();
+    }
 
     protected void appendOrUpdatePriority(AutoCompletionListItem toAdd) {
Index: trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionManager.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionManager.java	(revision 7724)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionManager.java	(revision 7725)
@@ -7,7 +7,9 @@
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Objects;
 import java.util.Set;
 
@@ -54,4 +56,58 @@
 public class AutoCompletionManager implements DataSetListener {
 
+    /**
+     * Data class to remember tags that the user has entered.
+     */
+    public static class UserInputTag {
+        public String key;
+        public String value;
+        public boolean defaultKey;
+
+        /**
+         * Constructor.
+         * 
+         * @param key the tag key
+         * @param value the tag value
+         * @param defaultKey true, if the key was not really entered by the
+         * user, e.g. for preset text fields.
+         * In this case, the key will not get any higher priority, just the value.
+         */
+        public UserInputTag(String key, String value, boolean defaultKey) {
+            this.key = key;
+            this.value = value;
+            this.defaultKey = defaultKey;
+        }
+
+        @Override
+        public int hashCode() {
+            int hash = 7;
+            hash = 59 * hash + Objects.hashCode(this.key);
+            hash = 59 * hash + Objects.hashCode(this.value);
+            hash = 59 * hash + (this.defaultKey ? 1 : 0);
+            return hash;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == null) {
+                return false;
+            }
+            if (getClass() != obj.getClass()) {
+                return false;
+            }
+            final UserInputTag other = (UserInputTag) obj;
+            if (!Objects.equals(this.key, other.key)) {
+                return false;
+            }
+            if (!Objects.equals(this.value, other.value)) {
+                return false;
+            }
+            if (this.defaultKey != other.defaultKey) {
+                return false;
+            }
+            return true;
+        }
+    }
+
     /** If the dirty flag is set true, a rebuild is necessary. */
     protected boolean dirty;
@@ -70,4 +126,9 @@
      */
     protected static final MultiMap<String, String> presetTagCache = new MultiMap<>();
+    /**
+     * Cache for tags that have been entered by the user.
+     */
+    protected static final Set<UserInputTag> userInputTagCache = new LinkedHashSet<>();
+    
     /**
      * the cached list of member roles
@@ -174,4 +235,11 @@
         }
     }
+    
+    
+    public static void rememberUserInput(String key, String value, boolean defaultKey) {
+        UserInputTag tag = new UserInputTag(key, value, defaultKey);
+        userInputTagCache.remove(tag); // re-add, so it gets to the last position of the LinkedHashSet
+        userInputTagCache.add(tag);
+    }
 
     /**
@@ -187,4 +255,15 @@
         return new ArrayList<>(presetTagCache.keySet());
     }
+    
+    protected Collection<String> getUserInputKeys() {
+        List<String> keys = new ArrayList<>();
+        for (UserInputTag tag : userInputTagCache) {
+            if (!tag.defaultKey) {
+                keys.add(tag.key);
+            }
+        }
+        Collections.reverse(keys);
+        return new LinkedHashSet<>(keys);
+    }
 
     /**
@@ -201,4 +280,15 @@
     protected static List<String> getPresetValues(String key) {
         return new ArrayList<>(presetTagCache.getValues(key));
+    }
+
+    protected static Collection<String> getUserInputValues(String key) {
+        ArrayList<String> values = new ArrayList<>();
+        for (UserInputTag tag : userInputTagCache) {
+            if (key.equals(tag.key)) {
+                values.add(tag.value);
+            }
+        }
+        Collections.reverse(values);
+        return new LinkedHashSet<>(values);
     }
 
@@ -261,4 +351,5 @@
         list.add(new AutoCompletionListItem("source", AutoCompletionItemPriority.IS_IN_STANDARD));
         list.add(getDataKeys(), AutoCompletionItemPriority.IS_IN_DATASET);
+        list.addUserInput(getUserInputKeys());
     }
 
@@ -285,4 +376,5 @@
             list.add(getPresetValues(key), AutoCompletionItemPriority.IS_IN_STANDARD);
             list.add(getDataValues(key), AutoCompletionItemPriority.IS_IN_DATASET);
+            list.addUserInput(getUserInputValues(key));
         }
     }
