diff --git a/data/defaultpresets.xml b/data/defaultpresets.xml
index d8a5172..ff22e70 100755
--- a/data/defaultpresets.xml
+++ b/data/defaultpresets.xml
@@ -38,13 +38,11 @@ combo: combo box, with multiple choices and possible to enter free form text
   values: comma separated list of values
   display_values: comma separated list of values to be displayed instead of the
                   database values, order and number must be equal to values
-  short_description: comma separated list of texts to be displayed below each
-                    display_value. (Only if it is not possible to describe 
-                    the entry in 2-3 words.) Instead of comma separeted list, you can
-                    also write it in the following form: 
-                        <short_description>first description</short_description>
-                                ...
-                        <short_description>last description</short_description>
+  short_descriptions: comma separated list of texts to be displayed below each
+                      display_value. (Only if it is not possible to describe
+                      the entry in 2-3 words.) Instead of comma separeted list
+  instead using values, display_values and short_descriptions, the following form is also supported:
+    <list_item value="" display_value="' short_description="" icon=""/>
   default: default string to display
   delete_if_empty: true/false
   use_last_as_default: true/false/force
@@ -54,17 +52,15 @@ multiselect: list of values from which zero or more can be selected
   text: fixed label to display
   delimiter: character that separates values (default: semicolon) - this
              will also be used to separate selected values in the tag.
-  values: delimiter-separated list of values (delimiter can be escaped with backslash)
   rows: specify the number of rows to display (default -1)
+  values: delimiter-separated list of values (delimiter can be escaped with backslash)
   display_values: delimiter-separated list of values to be displayed instead of the
                   database values, order and number must be equal to values
-  short_description: delimiter-separated list of texts to be displayed below each
-                    display_value. (Only if it is not possible to describe 
-                    the entry in 2-3 words.) Instead of a separated list, you can
-                    also write it in the following form: 
-                        <short_description>first description</short_description>
-                                ...
-                        <short_description>last description</short_description>
+  short_descriptions: delimiter-separated list of texts to be displayed below each
+                     display_value. (Only if it is not possible to describe
+                     the entry in 2-3 words.) Instead of a separated list
+  instead using values, display_values and short_descriptions, the following form is also supported:
+    <list_item value="" display_value="' short_description="" icon=""/>
   default: default string to display
   delete_if_empty: true/false
   use_last_as_default: true/false/force
@@ -690,13 +686,13 @@ are supplied, then "values" will be treated as "display_values" and translated i
             <key key="highway" value="path" />
             <optional>
                 <text key="name" text="Name" default="" delete_if_empty="true" />
-                <combo key="sac_scale" text="SAC Scale" values="hiking,mountain_hiking,demanding_mountain_hiking,alpine_hiking,demanding_alpine_hiking,difficult_alpine_hiking" default="" delete_if_empty="true" display_values="T1 - hiking trail,T2 - mountain hiking trail,T3 - difficult\, exposed hiking trail,T4 - difficult\, exposed\, steep alpine trail,T5 - difficult alpine trail with climbing,T6 - hazardous alpine trail with climbing">
-                    <short_description>Trail well cleared. Area flat or slightly sloped, no fall hazard</short_description>
-                    <short_description>Trail with continuous line and balanced ascent. Terrain partially steep, fall hazard possible</short_description>
-                    <short_description>exposed sites may be secured with ropes or chains, possible need to use hands for balance. Partly exposed sites with fall hazard, scree, pathless jagged rocks</short_description>
-                    <short_description>sometimes need for hand use to get ahead. Terrain quite exposed, precarious grassy acclivities, jagged rocks, facile snow-free glaciers.</short_description>
-                    <short_description>single plainly climbing up to second grade. Exposed, demanding terrain, jagged rocks, few dangerous glacier and snow</short_description>
-                    <short_description>climbing up to second grade. Often very exposed, precarious jagged rocks, glacier with danger to slip and fall</short_description>
+                <combo key="sac_scale" text="SAC Scale">
+                    <list_entry value="hiking" display_value="T1 - hiking trail" short_description="Trail well cleared. Area flat or slightly sloped, no fall hazard" />
+                    <list_entry value="mountain_hiking" display_value="T2 - mountain hiking trail" short_description="Trail with continuous line and balanced ascent. Terrain partially steep, fall hazard possible" />
+                    <list_entry value="demanding_mountain_hiking" display_value="T3 - difficult, exposed hiking trail" short_description="exposed sites may be secured with ropes or chains, possible need to use hands for balance. Partly exposed sites with fall hazard, scree, pathless jagged rocks" />
+                    <list_entry value="alpine_hiking" display_value="T4 - difficult, exposed, steep alpine trail" short_description="sometimes need for hand use to get ahead. Terrain quite exposed, precarious grassy acclivities, jagged rocks, facile snow-free glaciers" />
+                    <list_entry value="demanding_alpine_hiking" display_value="T5 - difficult alpine trail with climbing" short_description="single plainly climbing up to second grade. Exposed, demanding terrain, jagged rocks, few dangerous glacier and snow" />
+                    <list_entry value="difficult_alpine_hiking" display_value="T6 - hazardous alpine trail with climbing" short_description="climbing up to second grade. Often very exposed, precarious jagged rocks, glacier with danger to slip and fall" />
                 </combo>
                 <combo key="mtb:scale" text="MTB Scale" values="0,1,2,3,4,5" default="" delete_if_empty="true" />
                 <combo key="surface" text="Surface" values="paved,unpaved,asphalt,concrete,metal,wood,paving_stones,cobblestone,gravel,pebblestone,compacted,grass_paver,grass,sand,ground" default="" delete_if_empty="true" />
diff --git a/data/tagging-preset.xsd b/data/tagging-preset.xsd
index 64a0d4e..f4d17b8 100644
--- a/data/tagging-preset.xsd
+++ b/data/tagging-preset.xsd
@@ -125,10 +125,16 @@
 		<anyAttribute processContents="skip" />
 	</complexType>
 
+        <complexType name="list_entry">
+		<attribute name="value" type="string" use="required" />
+		<attribute name="display_value" type="string" />
+		<attribute name="short_description" type="string" />
+		<attribute name="icon" type="string" />
+	</complexType>
+
 	<complexType name="combo">
 		<sequence>
-			<element name="short_description" type="string" minOccurs="0"
-				maxOccurs="unbounded" />
+			<element name="list_entry" type="tns:list_entry" />
 		</sequence>
 		<attribute name="key" type="string" use="required" />
 		<attribute name="text" type="string" />
diff --git a/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java b/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java
index 86749ee..fa09340 100644
--- a/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java
+++ b/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java
@@ -7,6 +7,7 @@ import static org.openstreetmap.josm.tools.I18n.trn;
 
 import java.awt.Component;
 import java.awt.Dimension;
+import java.awt.Font;
 import java.awt.GridBagLayout;
 import java.awt.Image;
 import java.awt.Insets;
@@ -71,11 +72,11 @@ import org.openstreetmap.josm.gui.tagging.ac.AutoCompletingTextField;
 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionItemPritority;
 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionList;
 import org.openstreetmap.josm.gui.util.GuiHelper;
-import org.openstreetmap.josm.gui.widgets.HtmlPanel;
 import org.openstreetmap.josm.io.MirroredInputStream;
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.UrlLabel;
+import org.openstreetmap.josm.tools.Utils;
 import org.openstreetmap.josm.tools.XmlObjectParser;
 import org.openstreetmap.josm.tools.template_engine.ParseError;
 import org.openstreetmap.josm.tools.template_engine.TemplateEntry;
@@ -193,10 +194,13 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
         return returnValue;
     }
 
-    protected static class PresetListEntry {
-        String value;
-        String display_value;
-        String short_description;
+    public static class PresetListEntry {
+        public String value;
+        public String display_value;
+        public String short_description;
+        public String icon;
+        public String locale_display_value;
+        public String locale_short_description;
 
         public String getListDisplay() {
             if (value.equals(DIFFERENT))
@@ -205,28 +209,27 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
             if (value.equals(""))
                 return "&nbsp;";
 
-            StringBuilder res = new StringBuilder("<b>");
-            if (display_value != null) {
-                res.append(display_value);
-            } else {
-                res.append(value);
-            }
+            final StringBuilder res = new StringBuilder("<b>");
+            final String displ = Utils.firstNonNull(locale_display_value, tr(display_value), value);
+            res.append(displ);
             res.append("</b>");
-            if (short_description != null) {
+            final String descr = Utils.firstNonNull(locale_short_description, tr(short_description));
+            if (descr != null) {
                 // wrap in table to restrict the text width
-                res.append("<br><table><td width='232'>(").append(short_description).append(")</td></table>");
+                res.append("<div style=\"width:300px; padding:0 0 5px 5px\">").append(descr).append("</div>");
             }
             return res.toString();
         }
 
-        public PresetListEntry(String value) {
-            this.value = value;
-            this.display_value = value;
+        public ImageIcon getIcon() {
+            return icon == null ? null : ImageProvider.getIfAvailable(icon);
+        }
+
+        public PresetListEntry() {
         }
 
-        public PresetListEntry(String value, String display_value) {
+        public PresetListEntry(String value) {
             this.value = value;
-            this.display_value = display_value;
         }
 
         // toString is mainly used to initialize the Editor
@@ -234,7 +237,7 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
         public String toString() {
             if (value.equals(DIFFERENT))
                 return DIFFERENT;
-            return display_value.replaceAll("<.*>", ""); // remove additional markup, e.g. <br>
+            return display_value == null ? value : display_value.replaceAll("<.*>", ""); // remove additional markup, e.g. <br>
         }
     }
 
@@ -430,9 +433,8 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
         public String use_last_as_default = "false";
         public boolean required = false;
 
-        protected List<String> short_description_list;
         protected JComponent component;
-        protected Map<String, PresetListEntry> lhm;
+        protected Map<String, PresetListEntry> lhm = new LinkedHashMap<String, PresetListEntry>();
         protected Usage usage;
         protected Object originalValue;
 
@@ -444,37 +446,62 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
 
             // find out if our key is already used in the selection.
             usage = determineTextUsage(sel, key);
-            String def = default_;
-
-            char delChar = ';';
-            if (!delimiter.isEmpty()) {
-                delChar = delimiter.charAt(0);
-            }
-
-            String[] value_array = splitEscaped(delChar, values);
             String[] display_array;
-            String[] short_descriptions_array = null;
 
-            if (locale_display_values != null) {
-                display_array = splitEscaped(delChar, locale_display_values);
-            } else if (display_values != null) {
-                display_array = splitEscaped(delChar, display_values);
+            if (lhm.isEmpty()) {
+                display_array = initListEntriesFromAttributes();
             } else {
-                display_array = value_array;
+                if (values != null) {
+                    System.err.println(tr("Warning in tagging preset \"{0}-{1}\": "
+                            + "Ignoring ''{2}'' attribute as ''{3}'' elements are given.",
+                            key, text, "values", "list_entry"));
+                }
+                if (display_values != null || locale_display_values != null) {
+                    System.err.println(tr("Warning in tagging preset \"{0}-{1}\": "
+                            + "Ignoring ''{2}'' attribute as ''{3}'' elements are given.",
+                            key, text, "display_values", "list_entry"));
+                }
+                if (short_descriptions != null || locale_short_descriptions != null) {
+                    System.err.println(tr("Warning in tagging preset \"{0}-{1}\": "
+                            + "Ignoring ''{2}'' attribute as ''{3}'' elements are given.",
+                            key, text, "short_descriptions", "list_entry"));
+                }
+                display_array = new String[lhm.values().size()];
+                int i = 0;
+                for (PresetListEntry e : lhm.values()) {
+                    display_array[i++] = e.display_value;
+                }
             }
 
-            if (locale_short_descriptions != null) {
-                short_descriptions_array = splitEscaped(delChar, locale_short_descriptions);
-            } else if (short_descriptions != null) {
-                short_descriptions_array = splitEscaped(delChar, short_descriptions);
-            } else if (short_description_list != null) {
-                short_descriptions_array = short_description_list.toArray(new String[0]);
+            if (locale_text == null) {
+                if (text_context != null) {
+                    locale_text = trc(text_context, fixPresetString(text));
+                } else {
+                    locale_text = tr(fixPresetString(text));
+                }
             }
+            p.add(new JLabel(locale_text + ":"), GBC.std().insets(0, 0, 10, 0));
+
+            addToPanelAnchor(p, default_, display_array);
 
-            if (!"false".equals(use_last_as_default) && def == null && lastValue.containsKey(key)) {
-                def = lastValue.get(key);
+            return true;
+
+        }
+
+        private String[] initListEntriesFromAttributes() {
+            char delChar = ';';
+            if (!delimiter.isEmpty()) {
+                delChar = delimiter.charAt(0);
             }
 
+            String[] value_array = splitEscaped(delChar, values);
+
+            final String displ = Utils.firstNonNull(locale_display_values, display_values);
+            String[] display_array = displ == null ? value_array : splitEscaped(delChar, displ);
+            
+            final String descr = Utils.firstNonNull(locale_short_descriptions, short_descriptions);
+            String[] short_descriptions_array = descr == null ? null : splitEscaped(delChar, descr);
+
             if (display_array.length != value_array.length) {
                 System.err.println(tr("Broken tagging preset \"{0}-{1}\" - number of items in ''display_values'' must be the same as in ''values''", key, text));
                 display_array = value_array;
@@ -485,35 +512,23 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
                 short_descriptions_array = null;
             }
 
-            lhm = new LinkedHashMap<String, PresetListEntry>();
             if (!usage.hasUniqueValue() && !usage.unused()) {
                 lhm.put(DIFFERENT, new PresetListEntry(DIFFERENT));
             }
             for (int i = 0; i < value_array.length; i++) {
-                PresetListEntry e = new PresetListEntry(value_array[i]);
-                e.display_value = (locale_display_values == null)
-                        ? (values_context == null ? tr(fixPresetString(display_array[i]))
-                                : trc(values_context, fixPresetString(display_array[i]))) : display_array[i];
-                        if (short_descriptions_array != null) {
-                            e.short_description = locale_short_descriptions == null ? tr(fixPresetString(short_descriptions_array[i]))
-                                    : fixPresetString(short_descriptions_array[i]);
-                        }
-                        lhm.put(value_array[i], e);
-            }
-
-            if (locale_text == null) {
-                if (text_context != null) {
-                    locale_text = trc(text_context, fixPresetString(text));
-                } else {
-                    locale_text = tr(fixPresetString(text));
+                final PresetListEntry e = new PresetListEntry(value_array[i]);
+                e.locale_display_value = locale_display_values != null
+                        ? display_array[i]
+                        : trc(values_context, fixPresetString(display_array[i]));
+                if (short_descriptions_array != null) {
+                    e.locale_short_description = locale_short_descriptions != null
+                            ? short_descriptions_array[i]
+                            : tr(fixPresetString(short_descriptions_array[i]));
                 }
+                lhm.put(value_array[i], e);
             }
-            p.add(new JLabel(locale_text + ":"), GBC.std().insets(0, 0, 10, 0));
-
-            addToPanelAnchor(p, def, display_array);
-
-            return true;
 
+            return display_array;
         }
 
         protected String getDisplayIfNull(String display) {
@@ -560,11 +575,14 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
             changedTags.add(new Tag(key, value));
         }
 
-        public void setShort_description(String s) {
-            if (short_description_list == null) {
-                short_description_list = new ArrayList<String>();
+        public void addListEntry(PresetListEntry e) {
+            lhm.put(e.value, e);
+        }
+
+        public void addListEntries(Collection<PresetListEntry> e) {
+            for (PresetListEntry i : e) {
+                addListEntry(i);
             }
-            short_description_list.add(tr(s));
         }
 
         @Override
@@ -575,7 +593,7 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
         protected ListCellRenderer getListCellRenderer() {
             return new ListCellRenderer() {
 
-                HtmlPanel lbl = new HtmlPanel();
+                JLabel lbl = new JLabel();
                 JComponent dummy = new JComponent() {
                 };
 
@@ -594,8 +612,10 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
                     }
 
                     PresetListEntry item = (PresetListEntry) value;
-                    String s = item.getListDisplay();
-                    lbl.setText(s);
+                    lbl.setOpaque(true);
+                    lbl.setFont(lbl.getFont().deriveFont(Font.PLAIN));
+                    lbl.setText("<html>" + item.getListDisplay() + "</html>");
+                    lbl.setIcon(item.getIcon());
                     lbl.setEnabled(list.isEnabled());
                     // We do not want the editor to have the maximum height of all
                     // entries. Return a dummy with bogus height.
@@ -1140,9 +1160,11 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
         parser.map("label", Label.class);
         parser.map("space", Space.class);
         parser.map("key", Key.class);
+        parser.map("list_entry", PresetListEntry.class);
         LinkedList<TaggingPreset> all = new LinkedList<TaggingPreset>();
         TaggingPresetMenu lastmenu = null;
         Roles lastrole = null;
+        List<PresetListEntry> listEntries = new LinkedList<PresetListEntry>();
 
         if (validate) {
             parser.startWithValidation(in, "http://josm.openstreetmap.de/tagging-preset-1.0", "resource://data/tagging-preset.xsd");
@@ -1176,18 +1198,23 @@ public class TaggingPreset extends AbstractAction implements MapView.LayerChange
                 all.add(tp);
                 lastrole = null;
             } else {
-                if(all.size() != 0) {
-                    if(o instanceof Roles) {
-                        all.getLast().data.add((Item)o);
+                if (all.size() != 0) {
+                    if (o instanceof Roles) {
+                        all.getLast().data.add((Item) o);
                         lastrole = (Roles) o;
-                    }
-                    else if(o instanceof Role) {
-                        if(lastrole == null)
+                    } else if (o instanceof Role) {
+                        if (lastrole == null) {
                             throw new SAXException(tr("Preset role element without parent"));
+                        }
                         lastrole.roles.add((Role) o);
-                    }
-                    else {
-                        all.getLast().data.add((Item)o);
+                    } else if (o instanceof PresetListEntry) {
+                        listEntries.add((PresetListEntry) o);
+                    } else {
+                        all.getLast().data.add((Item) o);
+                        if (o instanceof ComboMultiSelect) {
+                            ((ComboMultiSelect) o).addListEntries(listEntries);
+                        }
+                        listEntries = new LinkedList<PresetListEntry>();
                         lastrole = null;
                     }
                 } else
diff --git a/src/org/openstreetmap/josm/tools/Utils.java b/src/org/openstreetmap/josm/tools/Utils.java
index 8c26f43..2ea3c7d 100644
--- a/src/org/openstreetmap/josm/tools/Utils.java
+++ b/src/org/openstreetmap/josm/tools/Utils.java
@@ -62,9 +62,18 @@ public class Utils {
         return null;
     }
 
-	public static <T> Collection<T> filter(Collection<? extends T> collection, Predicate<? super T> predicate) {
-		return new FilteredCollection<T>(collection, predicate);
-	}
+    public static <T> Collection<T> filter(Collection<? extends T> collection, Predicate<? super T> predicate) {
+        return new FilteredCollection<T>(collection, predicate);
+    }
+
+    public static <T> T firstNonNull(T... items) {
+        for (T i : items) {
+            if (i != null) {
+                return i;
+            }
+        }
+        return null;
+    }
 
     /**
      * Filter a collection by (sub)class.
