Index: trunk/src/org/openstreetmap/josm/gui/preferences/TaggingPresetPreference.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/TaggingPresetPreference.java	(revision 816)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/TaggingPresetPreference.java	(revision 824)
@@ -29,4 +29,6 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.tagging.TaggingPreset;
+import org.openstreetmap.josm.gui.tagging.TaggingPresetMenu;
+import org.openstreetmap.josm.gui.tagging.TaggingPresetSeperator;
 import org.openstreetmap.josm.tools.GBC;
 
@@ -127,40 +129,25 @@
 		else
 		{
-			HashMap<String,JMenu> submenus = new HashMap<String,JMenu>();
+			HashMap<TaggingPresetMenu,JMenu> submenus = new HashMap<TaggingPresetMenu,JMenu>();
 			for (final TaggingPreset p : taggingPresets) {
 				String name = (String) p.getValue(Action.NAME);
-				if (name.equals(" ")) {
-					Main.main.menu.presetsMenu.add(new JSeparator());
+				if (p instanceof TaggingPresetSeperator) {
+					if(p.group != null)
+						submenus.get(p.group).add(new JSeparator());
+					else
+						Main.main.menu.presetsMenu.add(new JSeparator());
+				}
+				else if (p instanceof TaggingPresetMenu)
+				{
+					JMenu submenu = new JMenu(p);
+					submenus.put((TaggingPresetMenu)p, submenu);
+					Main.main.menu.presetsMenu.add(submenu);
 				} else {
-					String[] sp = name.split("/");
-					if (sp.length <= 1) {
-						if(p.isEmpty())
-						{
-							JMenu submenu = submenus.get(sp[0]);
-							if (submenu == null) {
-								submenu = new JMenu(p);
-								submenus.put(sp[0], submenu);
-								Main.main.menu.presetsMenu.add(submenu);
-							}
-						}
-						else
-						{
-							Main.main.menu.presetsMenu.add(new JMenuItem(p));
-						}
-					} else {
-						p.setDisplayName(sp[1]);
-						JMenu submenu = submenus.get(sp[0]);
-						if (submenu == null) {
-							submenu = new JMenu(sp[0]);
-							submenus.put(sp[0], submenu);
-							Main.main.menu.presetsMenu.add(submenu);
-						}
-						if (sp[1].equals(" "))
-							submenu.add(new JSeparator());
-						else
-							submenu.add(p);
-					}
+					if(p.group != null)
+						submenus.get(p.group).add(p);
+					else
+						Main.main.menu.presetsMenu.add(new JMenuItem(p));
 				}
-			}		
+			}
 		}
 	}
Index: trunk/src/org/openstreetmap/josm/gui/preferences/ToolbarPreferences.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/ToolbarPreferences.java	(revision 816)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/ToolbarPreferences.java	(revision 824)
@@ -145,7 +145,5 @@
 		for (Action a : actions.values())
 		{
-			String name = a.getValue(a.NAME).toString();
-			if(!name.equals(" "))
-				us.put(a.getValue(a.NAME).toString()+a.toString(), a);
+			us.put(a.getValue(a.NAME).toString()+a.toString(), a);
 		}
 		for (String a : us.keySet())
Index: trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java	(revision 816)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java	(revision 824)
@@ -41,4 +41,6 @@
 import org.openstreetmap.josm.data.osm.OsmUtils;
 import org.openstreetmap.josm.gui.QuadStateCheckBox;
+import org.openstreetmap.josm.gui.tagging.TaggingPresetMenu;
+import org.openstreetmap.josm.gui.tagging.TaggingPresetSeperator;
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
@@ -54,5 +56,8 @@
  */
 public class TaggingPreset extends AbstractAction {
-	
+
+	public TaggingPresetMenu group = null;
+	public String name;
+
 	public static abstract class Item {
 		public boolean focus = false;
@@ -331,24 +336,22 @@
 	public TaggingPreset() {}
 
-
-	public boolean isEmpty()
-	{
-		return (data.size() == 0);
-	}
-	/**
-	 * Called from the XML parser to set the name of the tagging preset
-	 */
-	public void setName(String name) {
-		setDisplayName(tr(name));
-		putValue("toolbar", "tagging_"+name);
-	}
-	
 	/**
 	 * Change the display name without changing the toolbar value.
 	 */
-	public void setDisplayName(String name) {
-		putValue(Action.NAME, tr(name));
-		String tooltip = tr("Use preset ''{0}''", tr(name));
-		putValue(SHORT_DESCRIPTION, "<html>"+tooltip+"</html>");
+	public void setDisplayName() {
+		if(group == null)
+		{
+			putValue(Action.NAME, tr(name));
+			String tooltip = tr("Use preset ''{0}''", tr(name));
+			putValue(SHORT_DESCRIPTION, "<html>"+tooltip+"</html>");
+			putValue("toolbar", "tagging_" + name);
+		}
+		else
+		{
+			putValue(Action.NAME, tr(group.name) + "/" + tr(name));
+			String tooltip = tr("Use preset ''{0}'' of group ''{1}''", tr(name), tr(group.name));
+			putValue(SHORT_DESCRIPTION, "<html>"+tooltip+"</html>");
+			putValue("toolbar", "tagging_" + group.name + "/" + name);
+		}
 	}
 
@@ -395,4 +398,6 @@
 		XmlObjectParser parser = new XmlObjectParser();
 		parser.mapOnStart("item", TaggingPreset.class);
+		parser.mapOnStart("seperator", TaggingPresetSeperator.class);
+		parser.mapBoth("group", TaggingPresetMenu.class);
 		parser.map("text", Text.class);
 		parser.map("check", Check.class);
@@ -401,10 +406,30 @@
 		parser.map("key", Key.class);
 		LinkedList<TaggingPreset> all = new LinkedList<TaggingPreset>();
+		TaggingPresetMenu lastmenu = null;
 		parser.start(in);
 		while(parser.hasNext()) {
 			Object o = parser.next();
-			if (o instanceof TaggingPreset) {
-				all.add((TaggingPreset)o);
-				Main.toolbar.register((TaggingPreset)o);
+			if (o instanceof TaggingPresetMenu) {
+				TaggingPresetMenu tp = (TaggingPresetMenu) o;
+				if(tp == lastmenu)
+					lastmenu = null;
+				else
+				{
+					tp.setDisplayName();
+					lastmenu = tp;
+					all.add(tp);
+					Main.toolbar.register(tp);
+					
+				}
+			} else if (o instanceof TaggingPresetSeperator) {
+				TaggingPresetSeperator tp = (TaggingPresetSeperator) o;
+				tp.group = lastmenu;
+				all.add(tp);
+			} else if (o instanceof TaggingPreset) {
+				TaggingPreset tp = (TaggingPreset) o;
+				tp.group = lastmenu;
+				tp.setDisplayName();
+				all.add(tp);
+				Main.toolbar.register(tp);
 			} else
 				all.getLast().data.add((Item)o);
Index: trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPresetMenu.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPresetMenu.java	(revision 824)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPresetMenu.java	(revision 824)
@@ -0,0 +1,20 @@
+// License: GPL. Copyright 2007 by Immanuel Scholz and others
+package org.openstreetmap.josm.gui.tagging;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import javax.swing.Action;
+
+import org.openstreetmap.josm.gui.tagging.TaggingPreset;
+
+public class TaggingPresetMenu extends TaggingPreset {
+	public void setDisplayName() {
+		putValue(Action.NAME, tr(name));
+		String tooltip = tr("Preset group ''{0}''", tr(name));
+		putValue(SHORT_DESCRIPTION, "<html>"+tooltip+"</html>");
+		putValue("toolbar", "tagginggroup_" + name);
+	}
+	public void setIcon(String iconName) {
+		super.setIcon(iconName);
+	}
+}
Index: trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPresetSeperator.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPresetSeperator.java	(revision 824)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPresetSeperator.java	(revision 824)
@@ -0,0 +1,8 @@
+// License: GPL. Copyright 2007 by Immanuel Scholz and others
+package org.openstreetmap.josm.gui.tagging;
+
+import org.openstreetmap.josm.gui.tagging.TaggingPreset;
+
+public class TaggingPresetSeperator extends TaggingPreset {
+	public void setDisplayName() {}
+}
Index: trunk/src/org/openstreetmap/josm/tools/XmlObjectParser.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/XmlObjectParser.java	(revision 816)
+++ trunk/src/org/openstreetmap/josm/tools/XmlObjectParser.java	(revision 824)
@@ -67,4 +67,11 @@
 				if (mapping.get(qname).onStart)
 					report();
+				if (mapping.get(qname).both)
+				{
+					try {
+						queue.put(current.peek());
+					} catch (InterruptedException e) {
+					}
+				}
 			}
 		}
@@ -156,8 +163,10 @@
 		Class<?> klass;
 		boolean onStart;
-		public Entry(Class<?> klass, boolean onStart) {
+		boolean both;
+		public Entry(Class<?> klass, boolean onStart, boolean both) {
 			super();
 			this.klass = klass;
 			this.onStart = onStart;
+			this.both = both;
 		}
 	}
@@ -209,9 +218,13 @@
 
 	public void map(String tagName, Class<?> klass) {
-		mapping.put(tagName, new Entry(klass,false));
+		mapping.put(tagName, new Entry(klass,false,false));
 	}
 
 	public void mapOnStart(String tagName, Class<?> klass) {
-		mapping.put(tagName, new Entry(klass,true));
+		mapping.put(tagName, new Entry(klass,true,false));
+	}
+
+	public void mapBoth(String tagName, Class<?> klass) {
+		mapping.put(tagName, new Entry(klass,false,true));
 	}
 
