Index: trunk/src/org/openstreetmap/josm/gui/dialogs/properties/PresetListPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/properties/PresetListPanel.java	(revision 5613)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/properties/PresetListPanel.java	(revision 5614)
@@ -21,5 +21,4 @@
 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.PresetType;
@@ -86,9 +85,5 @@
         }
 
-        for (TaggingPreset t : TaggingPresetPreference.taggingPresets) {
-            if (!t.matches(types, tags, true)) {
-                continue;
-            }
-
+        for (TaggingPreset t : TaggingPreset.getMatchingPresets(types, tags, true)) {
             JLabel lbl = new JLabel(t.getName() + " …");
             lbl.setIcon((Icon) t.getValue(Action.SMALL_ICON));
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java	(revision 5613)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java	(revision 5614)
@@ -62,4 +62,5 @@
 import org.openstreetmap.josm.gui.SideButton;
 import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec;
+import org.openstreetmap.josm.gui.dialogs.properties.PresetListPanel;
 import org.openstreetmap.josm.gui.dialogs.properties.PresetListPanel.PresetHandler;
 import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction;
@@ -115,13 +116,5 @@
                 WindowGeometry.centerInWindow(Main.parent, new Dimension(700, 650)));
 
-        // init the various models
-        //
-        memberTableModel = new MemberTableModel(getLayer());
-        memberTableModel.register();
-        selectionTableModel = new SelectionTableModel(getLayer());
-        selectionTableModel.register();
-        referrerModel = new ReferringRelationsBrowserModel(relation);
-
-        tagEditorPanel = new TagEditorPanel(new PresetHandler() {
+        final PresetHandler presetHandler = new PresetHandler() {
 
             @Override
@@ -136,5 +129,15 @@
                 return Collections.<OsmPrimitive>singletonList(relation);
             }
-        });
+        };
+
+        // init the various models
+        //
+        memberTableModel = new MemberTableModel(getLayer(), presetHandler);
+        memberTableModel.register();
+        selectionTableModel = new SelectionTableModel(getLayer());
+        selectionTableModel.register();
+        referrerModel = new ReferringRelationsBrowserModel(relation);
+
+        tagEditorPanel = new TagEditorPanel(presetHandler);
 
         // populate the models
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java	(revision 5613)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java	(revision 5614)
@@ -13,4 +13,5 @@
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -46,6 +47,8 @@
 import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
 import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
+import org.openstreetmap.josm.gui.dialogs.properties.PresetListPanel;
 import org.openstreetmap.josm.gui.dialogs.relation.WayConnectionType.Direction;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.gui.tagging.TaggingPreset;
 import org.openstreetmap.josm.gui.widgets.OsmPrimitivesTableModel;
 
@@ -59,6 +62,7 @@
 
     private DefaultListSelectionModel listSelectionModel;
-    private CopyOnWriteArrayList<IMemberModelListener> listeners;
-    private OsmDataLayer layer;
+    private final CopyOnWriteArrayList<IMemberModelListener> listeners;
+    private final OsmDataLayer layer;
+    private final PresetListPanel.PresetHandler presetHandler;
 
     private final int UNCONNECTED = Integer.MIN_VALUE;
@@ -73,8 +77,9 @@
      * constructor
      */
-    public MemberTableModel(OsmDataLayer layer) {
+    public MemberTableModel(OsmDataLayer layer, PresetListPanel.PresetHandler presetHandler) {
         members = new ArrayList<RelationMember>();
         listeners = new CopyOnWriteArrayList<IMemberModelListener>();
         this.layer = layer;
+        this.presetHandler = presetHandler;
         addTableModelListener(this);
     }
@@ -395,9 +400,11 @@
 
     private void addMembersAtIndex(List<? extends OsmPrimitive> primitives, int index) {
+        final Collection<TaggingPreset> presets = TaggingPreset.getMatchingPresets(EnumSet.of(TaggingPreset.PresetType.RELATION), presetHandler.getSelection().iterator().next().getKeys(), false);
         if (primitives == null)
             return;
         int idx = index;
         for (OsmPrimitive primitive : primitives) {
-            RelationMember member = new RelationMember("", primitive);
+            final String role = presets.isEmpty() ? null : presets.iterator().next().suggestRoleForOsmPrimitive(primitive);
+            RelationMember member = new RelationMember(role == null ? "" : role, primitive);
             members.add(idx++, member);
         }
Index: trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java	(revision 5613)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java	(revision 5614)
@@ -67,4 +67,5 @@
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.preferences.SourceEntry;
+import org.openstreetmap.josm.gui.preferences.map.TaggingPresetPreference;
 import org.openstreetmap.josm.gui.preferences.map.TaggingPresetPreference.PresetPrefHelper;
 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletingTextField;
@@ -76,4 +77,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Predicate;
 import org.openstreetmap.josm.tools.UrlLabel;
 import org.openstreetmap.josm.tools.Utils;
@@ -1094,4 +1096,5 @@
         public String text_context;
         public String locale_text;
+        public Match memberExpression;
 
         public boolean required = false;
@@ -1107,4 +1110,12 @@
             } else if(!"optional".equals(str))
                 throw new SAXException(tr("Unknown requisite: {0}", str));
+        }
+
+        public void setMember_expression(String member_expression) throws SAXException {
+            try {
+                this.memberExpression = SearchCompiler.compile(member_expression, true, true);
+            } catch (SearchCompiler.ParseError ex) {
+                throw new SAXException(tr("Illegal member expression: {0}", ex.getMessage()), ex);
+            }
         }
 
@@ -1158,5 +1169,5 @@
     public static class Roles extends Item {
 
-        public List<Role> roles = new LinkedList<Role>();
+        public final List<Role> roles = new LinkedList<Role>();
 
         @Override
@@ -1241,4 +1252,5 @@
     public EnumSet<PresetType> types;
     public List<Item> data = new LinkedList<Item>();
+    public Roles roles;
     public TemplateEntry nameTemplate;
     public Match nameTemplateFilter;
@@ -1428,4 +1440,8 @@
                     if (o instanceof Roles) {
                         all.getLast().data.add((Item) o);
+                        if (all.getLast().roles != null) {
+                            throw new SAXException(tr("Roles cannot appear more than once"));
+                        }
+                        all.getLast().roles = (Roles) o;
                         lastrole = (Roles) o;
                     } else if (o instanceof Role) {
@@ -1572,4 +1588,16 @@
     }
 
+    public String suggestRoleForOsmPrimitive(OsmPrimitive osm) {
+        if (roles == null) {
+            return null;
+        }
+        for (Role i : roles.roles) {
+            if (i.memberExpression != null && i.memberExpression.match(osm)) {
+                return i.key;
+            }
+        }
+        return null;
+    }
+
     public void actionPerformed(ActionEvent e) {
         if (Main.main == null) return;
@@ -1590,6 +1618,7 @@
                 r.put(t.getKey(), t.getValue());
             }
-            for(OsmPrimitive osm : Main.main.getCurrentDataSet().getSelected()) {
-                RelationMember rm = new RelationMember("", osm);
+            for (OsmPrimitive osm : Main.main.getCurrentDataSet().getSelected()) {
+                String role = suggestRoleForOsmPrimitive(osm);
+                RelationMember rm = new RelationMember(role == null ? "" : role, osm);
                 r.addMember(rm);
                 members.add(rm);
@@ -1773,3 +1802,12 @@
         return atLeastOnePositiveMatch;
     }
+
+    public static Collection<TaggingPreset> getMatchingPresets(final Collection<PresetType> t, final Map<String, String> tags, final boolean onlyShowable) {
+        return Utils.filter(TaggingPresetPreference.taggingPresets, new Predicate<TaggingPreset>() {
+            @Override
+            public boolean evaluate(TaggingPreset object) {
+                return object.matches(t, tags, onlyShowable);
+            }
+        });
+    }
 }
