diff --git a/src/org/openstreetmap/josm/gui/dialogs/properties/PresetListPanel.java b/src/org/openstreetmap/josm/gui/dialogs/properties/PresetListPanel.java
index 3c63305..fe03b79 100644
--- a/src/org/openstreetmap/josm/gui/dialogs/properties/PresetListPanel.java
+++ b/src/org/openstreetmap/josm/gui/dialogs/properties/PresetListPanel.java
@@ -10,7 +10,6 @@ import java.awt.event.MouseListener;
 import java.awt.font.TextAttribute;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
 
@@ -23,10 +22,7 @@ import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Tag;
 import org.openstreetmap.josm.gui.preferences.map.TaggingPresetPreference;
 import org.openstreetmap.josm.gui.tagging.TaggingPreset;
-import org.openstreetmap.josm.gui.tagging.TaggingPreset.Check;
-import org.openstreetmap.josm.gui.tagging.TaggingPreset.Combo;
 import org.openstreetmap.josm.gui.tagging.TaggingPreset.PresetType;
-import org.openstreetmap.josm.gui.tagging.TaggingPreset.Text;
 import org.openstreetmap.josm.tools.GBC;
 
 public class PresetListPanel extends JPanel {
@@ -81,71 +77,26 @@ public class PresetListPanel extends JPanel {
         public void mouseReleased(MouseEvent arg0) {}
     }
 
-    public void updatePresets(int nodes, int ways, int relations, int closedways, Map<String, Map<String, Integer>> valueCount, PresetHandler presetHandler)  {
+    public void updatePresets(final Collection<PresetType> types, final Map<String, String> tags, PresetHandler presetHandler) {
 
         removeAll();
-        int total = nodes+ways+relations+closedways;
-        if(total == 0) {
+        if (types.isEmpty()) {
             setVisible(false);
             return;
         }
 
-        for(TaggingPreset t : TaggingPresetPreference.taggingPresets) {
-            if(
-                    (       t.types == null
-                            || (relations > 0 && t.types.contains(PresetType.RELATION))
-                            || (nodes > 0 && t.types.contains(PresetType.NODE))
-                            || (ways+closedways > 0 && t.types.contains(PresetType.WAY))
-                            || (closedways > 0 && t.types.contains(PresetType.CLOSEDWAY))
-                    )
-                    && t.isShowable())
-            {
-                int found = 0;
-                for(TaggingPreset.Item i : t.data) {
-                    if(i instanceof TaggingPreset.Key) {
-                        String val = ((TaggingPreset.Key)i).value;
-                        String key = ((TaggingPreset.Key)i).key;
-                        // we subtract 100 if not found and add 1 if found
-                        found -= 100;
-                        if(key == null || !valueCount.containsKey(key)) {
-                            continue;
-                        }
-
-                        Map<String, Integer> v = valueCount.get(key);
-                        if(v.size() == 1 && val != null && v.containsKey(val) && v.get(val) == total) {
-                            found += 101;
-                        }
-                    } else {
-                        String key = null;
-                        if ((i instanceof Text) && ((Text)i).required) {
-                            key = ((Text)i).key;
-                        } else if ((i instanceof Combo) && ((Combo)i).required) {
-                            key = ((Combo)i).key;
-                        } else if ((i instanceof Check) && ((Check)i).required) {
-                            key = ((Check)i).key;
-                        }
-                        if (key != null) {
-                            if (valueCount.get(key) != null) {
-                                found += 1;
-                            } else {
-                                found -= 100;
-                            }
-                        }
-                    }
-                }
-
-                if(found <= 0) {
-                    continue;
-                }
-
-                JLabel lbl = new JLabel(t.getName() + " …");
-                lbl.setIcon((Icon) t.getValue(Action.SMALL_ICON));
-                lbl.addMouseListener(new PresetLabelML(lbl, t, presetHandler));
-                add(lbl, GBC.eol().fill(GBC.HORIZONTAL));
+        for (TaggingPreset t : TaggingPresetPreference.taggingPresets) {
+            if (!t.matches(types, tags)) {
+                continue;
             }
+
+            JLabel lbl = new JLabel(t.getName() + " …");
+            lbl.setIcon((Icon) t.getValue(Action.SMALL_ICON));
+            lbl.addMouseListener(new PresetLabelML(lbl, t, presetHandler));
+            add(lbl, GBC.eol().fill(GBC.HORIZONTAL));
         }
 
-        if(getComponentCount() > 0) {
+        if (getComponentCount() > 0) {
             setVisible(true);
             // This ensures the presets are exactly as high as needed.
             int height = getComponentCount() * getComponent(0).getHeight();
@@ -156,5 +107,4 @@ public class PresetListPanel extends JPanel {
             setVisible(false);
         }
     }
-
 }
diff --git a/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java b/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java
index 05a700e..5a9bca9 100644
--- a/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java
+++ b/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java
@@ -30,6 +30,7 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -103,6 +104,7 @@ import org.openstreetmap.josm.gui.dialogs.relation.DownloadRelationMemberTask;
 import org.openstreetmap.josm.gui.dialogs.relation.RelationEditor;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.tagging.TaggingPreset;
+import org.openstreetmap.josm.gui.tagging.TaggingPreset.PresetType;
 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletingComboBox;
 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionListItem;
 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionManager;
@@ -260,16 +262,15 @@ public class PropertiesDialog extends ToggleDialog implements SelectionChangedLi
                 Component c = super.getListCellRendererComponent(list, value,
                         index, isSelected, cellHasFocus);
                 if (c instanceof JLabel) {
-                    String str = null;
-                    str=((AutoCompletionListItem) value).getValue();
-                    if (valueCount.containsKey(objKey)){
-                        Map<String, Integer> m=valueCount.get(objKey);
+                    String str = ((AutoCompletionListItem) value).getValue();
+                    if (valueCount.containsKey(objKey)) {
+                        Map<String, Integer> m = valueCount.get(objKey);
                         if (m.containsKey(str)) {
-                            str+="("+m.get(str)+")";
-                            c.setFont(c.getFont().deriveFont(Font.ITALIC+Font.BOLD));
+                            str = tr("{0} ({1})", str, m.get(str));
+                            c.setFont(c.getFont().deriveFont(Font.ITALIC + Font.BOLD));
                         }
                     }
-                    ((JLabel)c).setText(str);
+                    ((JLabel) c).setText(str);
                 }
                 return c;
             }
@@ -946,45 +947,37 @@ public class PropertiesDialog extends ToggleDialog implements SelectionChangedLi
 
         // re-load property data
         propertyData.setRowCount(0);
-        int nodes = 0;
-        int ways = 0;
-        int relations = 0;
-        int closedways = 0;
 
-        Map<String, Integer> keyCount = new HashMap<String, Integer>();
+        final Map<String, Integer> keyCount = new HashMap<String, Integer>();
+        final Map<String, String> tags = new HashMap<String, String>();
         valueCount.clear();
+        EnumSet<PresetType> types = EnumSet.noneOf(TaggingPreset.PresetType.class);
         for (OsmPrimitive osm : newSelection) {
-            if(osm instanceof Node) {
-                ++nodes;
-            } else if(osm instanceof Relation) {
-                ++relations;
-            } else if(((Way)osm).isClosed()) {
-                ++closedways;
-            } else {
-                ++ways;
-            }
-            for (String key: osm.keySet()) {
+            types.add(PresetType.forPrimitive(osm));
+            for (String key : osm.keySet()) {
                 String value = osm.get(key);
                 keyCount.put(key, keyCount.containsKey(key) ? keyCount.get(key) + 1 : 1);
                 if (valueCount.containsKey(key)) {
                     Map<String, Integer> v = valueCount.get(key);
-                    v.put(value, v.containsKey(value)? v.get(value) + 1 : 1 );
+                    v.put(value, v.containsKey(value) ? v.get(value) + 1 : 1);
                 } else {
-                    TreeMap<String,Integer> v = new TreeMap<String, Integer>();
+                    TreeMap<String, Integer> v = new TreeMap<String, Integer>();
                     v.put(value, 1);
                     valueCount.put(key, v);
                 }
             }
         }
         for (Entry<String, Map<String, Integer>> e : valueCount.entrySet()) {
-            int count=0;
-            for (Entry<String, Integer> e1: e.getValue().entrySet()) {
-                count+=e1.getValue();
+            int count = 0;
+            for (Entry<String, Integer> e1 : e.getValue().entrySet()) {
+                count += e1.getValue();
             }
             if (count < newSelection.size()) {
-                e.getValue().put("", newSelection.size()-count);
+                e.getValue().put("", newSelection.size() - count);
             }
             propertyData.addRow(new Object[]{e.getKey(), e.getValue()});
+            tags.put(e.getKey(), e.getValue().size() == 1
+                    ? e.getValue().keySet().iterator().next() : tr("<different>"));
         }
 
         membershipData.setRowCount(0);
@@ -1025,7 +1018,7 @@ public class PropertiesDialog extends ToggleDialog implements SelectionChangedLi
             membershipData.addRow(new Object[]{r, roles.get(r)});
         }
 
-        presets.updatePresets(nodes, ways, relations, closedways, valueCount, presetHandler);
+        presets.updatePresets(types, tags, presetHandler);
 
         membershipTable.getTableHeader().setVisible(membershipData.getRowCount() > 0);
         membershipTable.setVisible(membershipData.getRowCount() > 0);
diff --git a/src/org/openstreetmap/josm/gui/tagging/TagEditorPanel.java b/src/org/openstreetmap/josm/gui/tagging/TagEditorPanel.java
index 55fc577..65fbc8e 100644
--- a/src/org/openstreetmap/josm/gui/tagging/TagEditorPanel.java
+++ b/src/org/openstreetmap/josm/gui/tagging/TagEditorPanel.java
@@ -5,9 +5,7 @@ import java.awt.BorderLayout;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
 import java.awt.Insets;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
+import java.util.EnumSet;
 
 import javax.swing.BoxLayout;
 import javax.swing.JButton;
@@ -180,13 +178,9 @@ public class TagEditorPanel extends JPanel {
     }
 
     private void updatePresets() {
-        Map<String, Map<String, Integer>> valuesCount = new HashMap<String, Map<String,Integer>>();
-        for (Entry<String, String> entry: model.getTags().entrySet()) {
-            Map<String, Integer> values = new HashMap<String, Integer>();
-            values.put(entry.getValue(), 1);
-            valuesCount.put(entry.getKey(), values);
-        }
-        presetListPanel.updatePresets(0, 0, 1, 0, valuesCount, presetHandler);
+        presetListPanel.updatePresets(
+                EnumSet.of(TaggingPreset.PresetType.RELATION),
+                model.getTags(), presetHandler);
         validate();
     }
 }
diff --git a/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java b/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java
index 5d23549..bd40aac 100644
--- a/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java
+++ b/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java
@@ -107,6 +107,65 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
         public String getName() {
             return name().toLowerCase();
         }
+
+        public static PresetType forPrimitive(OsmPrimitive p) {
+            return forPrimitiveType(p.getDisplayType());
+        }
+
+        public static PresetType forPrimitiveType(org.openstreetmap.josm.data.osm.OsmPrimitiveType type) {
+            switch (type) {
+                case NODE:
+                    return NODE;
+                case WAY:
+                    return WAY;
+                case CLOSEDWAY:
+                    return CLOSEDWAY;
+                case RELATION:
+                    return RELATION;
+                default:
+                    throw new IllegalArgumentException();
+            }
+        }
+    }
+
+    /**
+     * Enum denoting the way how a match (see {@link Item#matches}) is performed.
+     */
+    private enum MatchType {
+
+        /**
+         * Neutral, i.e., o not consider this item for matching.
+         */
+        NONE("none"), /**
+         * Positive if key matches, neutral otherwise.
+         */
+        KEY("key"),
+        /**
+         * Positive if key matches, negative otherwise.
+         */
+        KEY_REQUIRED("key!"),
+        /**
+         * Positive if key and value matches, negative otherwise.
+         */
+        KEY_VALUE("keyvalue");
+        private final String value;
+
+        private MatchType(String value) {
+            this.value = value;
+        }
+
+        public String getValue() {
+            return value;
+        }
+
+        public static MatchType ofString(String type) {
+            for (MatchType i : EnumSet.allOf(MatchType.class)) {
+                if (i.getValue().equals(type)) {
+                    return i;
+                }
+            }
+            throw new IllegalArgumentException(type + " is not allowed");
+        }
     }
 
     public static final int DIALOG_ANSWER_APPLY = 1;
@@ -139,6 +198,13 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
         boolean requestFocusInWindow() {
             return false;
         }
+
+        /**
+         * Tests whether the tags match this item.
+         * @param tags the tags of an {@link OsmPrimitive}
+         * @return {@code true} if matches (positive), {@code null} if neutral, {@code false} if mismatches (negative).
+         */
+        abstract Boolean matches(Map<String, String> tags);
     }
 
     public static class Usage {
@@ -244,11 +310,10 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
         public String text;
         public String locale_text;
         public String text_context;
-        public String default_;
+        public String default_ = "";
         public String originalValue;
         public String use_last_as_default = "false";
-        public boolean delete_if_empty = false;
-        public boolean required = false;
+        public String match = MatchType.NONE.getValue();
 
         private JComponent value;
 
@@ -315,9 +380,6 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
                     if (v.equals(originalValue) || (originalValue == null && v.length() == 0))
                         return;
 
-                    if (delete_if_empty && v.length() == 0) {
-                        v = null;
-                    }
                     changedTags.add(new Tag(key, v));
         }
 
@@ -325,6 +387,20 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
         boolean requestFocusInWindow() {
             return value.requestFocusInWindow();
         }
+
+        @Override
+        Boolean matches(Map<String, String> tags) {
+            switch (MatchType.ofString(match)) {
+                case NONE:
+                    return null;
+                case KEY:
+                    return tags.containsKey(key) ? true : null;
+                case KEY_REQUIRED:
+                    return tags.containsKey(key);
+                default:
+                    throw new IllegalArgumentException("key_value matching not supported for <text>: " + text);
+            }
+        }
     }
 
     public static class Check extends Item {
@@ -336,7 +412,7 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
         public String value_on = OsmUtils.trueval;
         public String value_off = OsmUtils.falseval;
         public boolean default_ = false; // only used for tagless objects
-        public boolean required = false;
+        public String match = MatchType.NONE.getValue();
 
         private QuadStateCheckBox check;
         private QuadStateCheckBox.State initialState;
@@ -410,6 +486,22 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
                             null));
         }
         @Override boolean requestFocusInWindow() {return check.requestFocusInWindow();}
+
+        @Override
+        Boolean matches(Map<String, String> tags) {
+            switch (MatchType.ofString(match)) {
+                case NONE:
+                    return null;
+                case KEY:
+                    return tags.containsKey(key) ? true : null;
+                case KEY_REQUIRED:
+                    return tags.containsKey(key);
+                case KEY_VALUE:
+                    return value_off.equals(tags.get(key)) || value_on.equals(tags.get(key));
+                default:
+                    throw new IllegalStateException();
+            }
+        }
     }
 
     public static abstract class ComboMultiSelect extends Item {
@@ -426,9 +518,8 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
         public String locale_short_descriptions;
         public String default_;
         public String delimiter = ";";
-        public boolean delete_if_empty = false;
         public String use_last_as_default = "false";
-        public boolean required = false;
+        public String match = MatchType.NONE.getValue();
 
         protected List<String> short_description_list;
         protected JComponent component;
@@ -439,6 +530,10 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
         protected abstract Object getSelectedItem();
         protected abstract void addToPanelAnchor(JPanel p, String def, String[] display_array);
 
+        protected char getDelChar() {
+            return delimiter.isEmpty() ? ';' : delimiter.charAt(0);
+        }
+
         @Override
         public boolean addToPanel(JPanel p, Collection<OsmPrimitive> sel) {
 
@@ -446,10 +541,7 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
             usage = determineTextUsage(sel, key);
             String def = default_;
 
-            char delChar = ';';
-            if (!delimiter.isEmpty()) {
-                delChar = delimiter.charAt(0);
-            }
+            char delChar = getDelChar();
 
             String[] value_array = splitEscaped(delChar, values);
             String[] display_array;
@@ -551,9 +643,6 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
             } else if (value.equals(originalValue.toString()))
                 return;
 
-            if (delete_if_empty && value.length() == 0) {
-                value = null;
-            }
             if (!"false".equals(use_last_as_default)) {
                 lastValue.put(key, value);
             }
@@ -607,6 +696,23 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
                 }
             };
         }
+
+        @Override
+        Boolean matches(Map<String, String> tags) {
+            switch (MatchType.ofString(match)) {
+                case NONE:
+                    return null;
+                case KEY:
+                    return tags.containsKey(key) ? true : null;
+                case KEY_REQUIRED:
+                    return tags.containsKey(key);
+                case KEY_VALUE:
+                    return tags.containsKey(key)
+                            && Arrays.asList(splitEscaped(getDelChar(), values)).contains(tags.get(key));
+                default:
+                    throw new IllegalStateException();
+            }
+        }
     }
 
     public static class Combo extends ComboMultiSelect {
@@ -827,6 +933,11 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
         @Override
         public void addCommands(List<Tag> changedTags) {
         }
+
+        @Override
+        Boolean matches(Map<String, String> tags) {
+            return null;
+        }
     }
 
     public static class Link extends Item {
@@ -861,6 +972,11 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
         @Override
         public void addCommands(List<Tag> changedTags) {
         }
+
+        @Override
+        Boolean matches(Map<String, String> tags) {
+            return null;
+        }
     }
 
     public static class Role {
@@ -870,7 +986,7 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
         public String text_context;
         public String locale_text;
 
-        public boolean required=false;
+        public boolean required = false;
         public long count = 0;
 
         public void setType(String types) throws SAXException {
@@ -955,6 +1071,11 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
         @Override
         public void addCommands(List<Tag> changedTags) {
         }
+
+        @Override
+        Boolean matches(Map<String, String> tags) {
+            return null;
+        }
     }
 
     public static class Optional extends Item {
@@ -971,6 +1092,11 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
         @Override
         public void addCommands(List<Tag> changedTags) {
         }
+
+        @Override
+        Boolean matches(Map<String, String> tags) {
+            return null;
+        }
     }
 
     public static class Space extends Item {
@@ -984,12 +1110,18 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
         @Override
         public void addCommands(List<Tag> changedTags) {
         }
+
+        @Override
+        Boolean matches(Map<String, String> tags) {
+            return null;
+        }
     }
 
     public static class Key extends Item {
 
         public String key;
         public String value;
+        public String match = MatchType.KEY_VALUE.getValue();
 
         @Override
         public boolean addToPanel(JPanel p, Collection<OsmPrimitive> sel) {
@@ -1000,6 +1132,22 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
         public void addCommands(List<Tag> changedTags) {
             changedTags.add(new Tag(key, value));
         }
+
+        @Override
+        Boolean matches(Map<String, String> tags) {
+            switch (MatchType.ofString(match)) {
+                case NONE:
+                    return null;
+                case KEY:
+                    return tags.containsKey(key) ? true : null;
+                case KEY_REQUIRED:
+                    return tags.containsKey(key);
+                case KEY_VALUE:
+                    return value.equals(tags.get(key));
+                default:
+                    throw new IllegalStateException();
+            }
+        }
     }
 
     /**
@@ -1485,4 +1633,22 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
     public String toString() {
         return (types == null?"":types) + " " + name;
     }
+
+    public boolean matches(Collection<PresetType> t, Map<String, String> tags) {
+        if (!isShowable()) {
+            return false;
+        } else if (t != null && types != null && !types.containsAll(t)) {
+            return false;
+        }
+        boolean atLeastOnePositiveMatch = false;
+        for (Item item : data) {
+            Boolean m = item.matches(tags);
+            if (m != null && !m) {
+                return false;
+            } else if (m != null) {
+                atLeastOnePositiveMatch = true;
+            }
+        }
+        return atLeastOnePositiveMatch;
+    }
 }
diff --git a/src/org/openstreetmap/josm/tools/TaggingPresetNameTemplateList.java b/src/org/openstreetmap/josm/tools/TaggingPresetNameTemplateList.java
index 6792206..c9e252a 100644
--- a/src/org/openstreetmap/josm/tools/TaggingPresetNameTemplateList.java
+++ b/src/org/openstreetmap/josm/tools/TaggingPresetNameTemplateList.java
@@ -1,17 +1,14 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.tools;
 
-import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.LinkedList;
 import java.util.List;
 
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.gui.preferences.map.TaggingPresetPreference;
 import org.openstreetmap.josm.gui.tagging.TaggingPreset;
-import org.openstreetmap.josm.gui.tagging.TaggingPreset.Check;
-import org.openstreetmap.josm.gui.tagging.TaggingPreset.Combo;
 import org.openstreetmap.josm.gui.tagging.TaggingPreset.PresetType;
-import org.openstreetmap.josm.gui.tagging.TaggingPreset.Text;
 
 /**
  * List of tagging presets with name templates, allows to find appropriate template based on existing primitive
@@ -26,12 +23,11 @@ public class TaggingPresetNameTemplateList {
         }
         return instance;
     }
-
-    private final List<TaggingPreset> presetsWithPattern = new ArrayList<TaggingPreset>();
+    private final List<TaggingPreset> presetsWithPattern = new LinkedList<TaggingPreset>();
 
     private TaggingPresetNameTemplateList() {
         if (TaggingPresetPreference.taggingPresets != null) {
-            for (TaggingPreset tp: TaggingPresetPreference.taggingPresets) {
+            for (TaggingPreset tp : TaggingPresetPreference.taggingPresets) {
                 if (tp.nameTemplate != null) {
                     presetsWithPattern.add(tp);
                 }
@@ -41,78 +37,11 @@ public class TaggingPresetNameTemplateList {
 
     public TaggingPreset findPresetTemplate(OsmPrimitive primitive) {
 
-        PresetType presetType;
-        switch (primitive.getType()) {
-        case NODE:
-            presetType = PresetType.NODE;
-            break;
-        case WAY:
-            if (((Way) primitive).isClosed()) {
-                presetType = PresetType.CLOSEDWAY;
-            } else {
-                presetType = PresetType.WAY;
+        for (TaggingPreset t : presetsWithPattern) {
+            if (t.matches(EnumSet.of(PresetType.forPrimitive(primitive)), primitive.getKeys())) {
+                return t;
             }
-            break;
-        case RELATION:
-            presetType = PresetType.RELATION;
-            break;
-        default:
-            throw new AssertionError();
         }
-
-        for(TaggingPreset t : presetsWithPattern) {
-
-
-            if (       t.types == null
-                    || t.types.contains(presetType)
-                    || (presetType == PresetType.CLOSEDWAY && t.types.contains(PresetType.WAY))) {
-                int found = 0;
-
-                if (t.nameTemplateFilter != null) {
-                    if (t.nameTemplateFilter.match(primitive))
-                        return t;
-                    else {
-                        continue;
-                    }
-                }
-
-                for(TaggingPreset.Item i : t.data) {
-                    if(i instanceof TaggingPreset.Key) {
-                        String val = ((TaggingPreset.Key)i).value;
-                        String key = ((TaggingPreset.Key)i).key;
-                        // we subtract 100 if not found and add 1 if found
-                        if (val != null && val.equals(primitive.get(key))) {
-                            found+=1;
-                        } else {
-                            found-=100;
-                        }
-                    } else {
-                        String key = null;
-                        if ((i instanceof Text) && ((Text)i).required) {
-                            key = ((Text)i).key;
-                        } else if ((i instanceof Combo) && ((Combo)i).required) {
-                            key = ((Combo)i).key;
-                        } else if ((i instanceof Check) && ((Check)i).required) {
-                            key = ((Check)i).key;
-                        }
-                        if (key != null) {
-                            if (primitive.get(key) != null) {
-                                found += 1;
-                            } else {
-                                found -= 100;
-                            }
-                        }
-                    }
-                }
-
-                if(found > 0)
-                    return t; // First matching preset wins
-            }
-        }
-
         return null;
-
     }
-
-
 }
