Index: applications/editors/josm/plugins/turnrestrictions/build.xml
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/build.xml	(revision 20484)
+++ applications/editors/josm/plugins/turnrestrictions/build.xml	(revision 20489)
@@ -31,8 +31,7 @@
 
 	<!-- enter the SVN commit message -->
-	<property name="commit.message" value="Commit message" />
+	<property name="commit.message" value="Second version of turnrestriction plugin. Still under development." />
 	<!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
-	<property name="plugin.main.version" value="" />
-
+	<property name="plugin.main.version" value="3136" />
 
 	<!--
Index: applications/editors/josm/plugins/turnrestrictions/data/test-data-set-1.osm
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/data/test-data-set-1.osm	(revision 20484)
+++ applications/editors/josm/plugins/turnrestrictions/data/test-data-set-1.osm	(revision 20489)
@@ -2,160 +2,175 @@
 <osm version='0.6' generator='JOSM'>
   <bounds minlat='46.9185552' minlon='7.3901081' maxlat='46.9271138' maxlon='7.4086475' origin='OpenStreetMap server' />
-  <node id='-86' action='modify' visible='true' lat='46.920401695281015' lon='7.392672484176534' />
-  <node id='-84' action='modify' visible='true' lat='46.91947481836078' lon='7.394608244994619' />
-  <node id='-82' visible='true' lat='46.91947481836078' lon='7.392692440473628' />
-  <node id='-81' visible='true' lat='46.9194611876982' lon='7.391036067814855' />
-  <node id='-71' visible='true' lat='46.920906018634135' lon='7.399118368137783' />
-  <node id='-69' visible='true' lat='46.921737460284035' lon='7.40135347341227' />
-  <node id='-67' visible='true' lat='46.921737460284035' lon='7.39909841184069' />
-  <node id='-66' visible='true' lat='46.921737460284035' lon='7.3971426947255114' />
-  <node id='-56' action='modify' visible='true' lat='46.92280059638277' lon='7.392991784930033' />
-  <node id='-54' action='modify' visible='true' lat='46.92175109036751' lon='7.394767895371367' />
-  <node id='-52' action='modify' visible='true' lat='46.92175109036752' lon='7.393011741227126' />
-  <node id='-51' action='modify' visible='true' lat='46.921737460284014' lon='7.390916330032293' />
-  <node id='-41' action='modify' visible='true' lat='46.92375467491946' lon='7.391245608934339' />
-  <node id='-40' action='modify' visible='true' lat='46.92378193405656' lon='7.394298922389664' />
-  <node id='-38' visible='true' lat='46.92450429613562' lon='7.394298922389665' />
-  <node id='-37' action='modify' visible='true' lat='46.924517925515175' lon='7.391285521528527' />
-  <node id='-28' visible='true' lat='46.925969434589156' lon='7.404077507965554' />
-  <node id='-26' visible='true' lat='46.925955805578894' lon='7.401802490096877' />
-  <node id='-25' visible='true' lat='46.925955805578894' lon='7.39940773444564' />
-  <node id='-12' timestamp='2010-03-09T09:06:53Z' visible='true' lat='46.92569685372496' lon='7.3913653467169' />
-  <node id='-10' timestamp='2010-03-09T09:06:53Z' visible='true' lat='46.92566959556225' lon='7.393261194940797' />
-  <node id='-8' timestamp='2010-03-09T09:06:53Z' visible='true' lat='46.92662362300419' lon='7.39328115123789' />
-  <node id='-6' timestamp='2010-03-09T09:06:53Z' visible='true' lat='46.9265827364623' lon='7.395296737244347' />
-  <node id='-4' timestamp='2010-03-09T09:06:53Z' visible='true' lat='46.9265827364623' lon='7.397511886221743' />
-  <node id='-2' timestamp='2010-03-09T09:06:53Z' visible='true' lat='46.925560562772716' lon='7.397471973627557' />
-  <way id='-88' action='modify' visible='true'>
-    <nd ref='-82' />
-    <nd ref='-84' />
+  <node id='-106' action='modify' visible='true' lat='46.92028078273882' lon='7.401045898188405' />
+  <node id='-104' action='modify' visible='true' lat='46.919302014885396' lon='7.401068288768116'>
+    <tag k='name' v='node 8.3' />
+  </node>
+  <node id='-103' action='modify' visible='true' lat='46.91930201488541' lon='7.399142698913044' />
+  <node id='-50' timestamp='2010-03-09T09:06:53Z' visible='true' lat='46.925560562772716' lon='7.397471973627557' />
+  <node id='-48' timestamp='2010-03-09T09:06:53Z' visible='true' lat='46.9265827364623' lon='7.397511886221743' />
+  <node id='-46' timestamp='2010-03-09T09:06:53Z' visible='true' lat='46.9265827364623' lon='7.395296737244347' />
+  <node id='-44' timestamp='2010-03-09T09:06:53Z' visible='true' lat='46.92662362300419' lon='7.39328115123789' />
+  <node id='-42' timestamp='2010-03-09T09:06:53Z' visible='true' lat='46.92566959556225' lon='7.393261194940797' />
+  <node id='-40' timestamp='2010-03-09T09:06:53Z' visible='true' lat='46.92569685372496' lon='7.3913653467169' />
+  <node id='-38' timestamp='2010-03-15T09:31:53Z' visible='true' lat='46.925955805578894' lon='7.39940773444564' />
+  <node id='-36' timestamp='2010-03-15T09:31:53Z' visible='true' lat='46.925955805578894' lon='7.401802490096877' />
+  <node id='-34' timestamp='2010-03-15T09:31:53Z' visible='true' lat='46.925969434589156' lon='7.404077507965554' />
+  <node id='-32' action='modify' timestamp='2010-03-15T09:31:53Z' visible='true' lat='46.924517925515175' lon='7.391285521528527' />
+  <node id='-30' timestamp='2010-03-15T09:31:53Z' visible='true' lat='46.92450429613562' lon='7.394298922389665' />
+  <node id='-28' action='modify' timestamp='2010-03-15T09:31:53Z' visible='true' lat='46.92378193405656' lon='7.394298922389664' />
+  <node id='-26' action='modify' timestamp='2010-03-15T09:31:53Z' visible='true' lat='46.92375467491946' lon='7.391245608934339' />
+  <node id='-24' action='modify' timestamp='2010-03-15T09:31:53Z' visible='true' lat='46.921737460284014' lon='7.390916330032293' />
+  <node id='-22' action='modify' timestamp='2010-03-15T09:31:53Z' visible='true' lat='46.92175109036752' lon='7.393011741227126' />
+  <node id='-20' action='modify' timestamp='2010-03-15T09:31:53Z' visible='true' lat='46.92175109036751' lon='7.394767895371367' />
+  <node id='-18' action='modify' timestamp='2010-03-15T09:31:53Z' visible='true' lat='46.92280059638277' lon='7.392991784930033' />
+  <node id='-16' timestamp='2010-03-15T09:31:53Z' visible='true' lat='46.921737460284035' lon='7.3971426947255114' />
+  <node id='-14' timestamp='2010-03-15T09:31:53Z' visible='true' lat='46.921737460284035' lon='7.39909841184069' />
+  <node id='-12' timestamp='2010-03-15T09:31:53Z' visible='true' lat='46.921737460284035' lon='7.40135347341227' />
+  <node id='-10' timestamp='2010-03-15T09:31:53Z' visible='true' lat='46.920906018634135' lon='7.399118368137783' />
+  <node id='-8' timestamp='2010-03-15T09:31:53Z' visible='true' lat='46.9194611876982' lon='7.391036067814855' />
+  <node id='-6' timestamp='2010-03-15T09:31:53Z' visible='true' lat='46.91947481836078' lon='7.392692440473628' />
+  <node id='-4' action='modify' timestamp='2010-03-15T09:31:53Z' visible='true' lat='46.91947481836078' lon='7.394608244994619' />
+  <node id='-2' action='modify' timestamp='2010-03-15T09:31:53Z' visible='true' lat='46.920401695281015' lon='7.392672484176534' />
+  <way id='-107' action='modify' visible='true'>
+    <nd ref='-104' />
+    <nd ref='-106' />
+    <tag k='name' v='way.8.2' />
+  </way>
+  <way id='-105' action='modify' visible='true'>
+    <nd ref='-103' />
+    <nd ref='-104' />
+    <tag k='name' v='way.8.1' />
+  </way>
+  <way id='-86' action='modify' timestamp='2010-03-09T09:06:53Z' visible='true'>
+    <nd ref='-48' />
+    <nd ref='-50' />
+    <tag k='name' v='Weg 2.2' />
+  </way>
+  <way id='-84' action='modify' timestamp='2010-03-09T09:06:53Z' visible='true'>
+    <nd ref='-46' />
+    <nd ref='-48' />
+    <tag k='name' v='Weg 2.1' />
+  </way>
+  <way id='-82' action='modify' timestamp='2010-03-09T09:06:53Z' visible='true'>
+    <nd ref='-42' />
+    <nd ref='-44' />
+    <tag k='name' v='Weg 1.2' />
+  </way>
+  <way id='-80' action='modify' timestamp='2010-03-09T09:06:53Z' visible='true'>
+    <nd ref='-40' />
+    <nd ref='-42' />
+    <tag k='name' v='Weg 1.1' />
+  </way>
+  <way id='-78' action='modify' timestamp='2010-03-15T09:31:53Z' visible='true'>
+    <nd ref='-38' />
+    <nd ref='-36' />
+    <tag k='name' v='Weg 3.1' />
+  </way>
+  <way id='-76' action='modify' timestamp='2010-03-15T09:31:53Z' visible='true'>
+    <nd ref='-36' />
+    <nd ref='-34' />
+    <tag k='name' v='Weg 3.2' />
+  </way>
+  <way id='-74' action='modify' timestamp='2010-03-15T09:31:53Z' visible='true'>
+    <nd ref='-32' />
+    <nd ref='-30' />
+    <tag k='name' v='way 4.1' />
+  </way>
+  <way id='-72' action='modify' timestamp='2010-03-15T09:31:53Z' visible='true'>
+    <nd ref='-28' />
+    <nd ref='-26' />
+    <tag k='name' v='way 4.2' />
+  </way>
+  <way id='-70' timestamp='2010-03-15T09:31:53Z' visible='true'>
+    <nd ref='-30' />
+    <nd ref='-28' />
+  </way>
+  <way id='-68' action='modify' timestamp='2010-03-15T09:31:53Z' visible='true'>
+    <nd ref='-24' />
+    <nd ref='-22' />
+    <tag k='name' v='way 5.1' />
+  </way>
+  <way id='-66' action='modify' timestamp='2010-03-15T09:31:53Z' visible='true'>
+    <nd ref='-22' />
+    <nd ref='-18' />
+    <tag k='name' v='way 5.2' />
+  </way>
+  <way id='-64' timestamp='2010-03-15T09:31:53Z' visible='true'>
+    <nd ref='-22' />
+    <nd ref='-20' />
+  </way>
+  <way id='-62' action='modify' timestamp='2010-03-15T09:31:53Z' visible='true'>
+    <nd ref='-16' />
+    <nd ref='-14' />
+    <tag k='name' v='way 6.1' />
+  </way>
+  <way id='-60' action='modify' timestamp='2010-03-15T09:31:53Z' visible='true'>
+    <nd ref='-14' />
+    <nd ref='-10' />
+    <tag k='name' v='way 6.2' />
+  </way>
+  <way id='-58' timestamp='2010-03-15T09:31:53Z' visible='true'>
+    <nd ref='-14' />
+    <nd ref='-12' />
+  </way>
+  <way id='-56' action='modify' timestamp='2010-03-15T09:31:53Z' visible='true'>
+    <nd ref='-8' />
+    <nd ref='-6' />
+    <tag k='name' v='way 7.1' />
+  </way>
+  <way id='-54' timestamp='2010-03-15T09:31:53Z' visible='true'>
+    <nd ref='-6' />
+    <nd ref='-2' />
+  </way>
+  <way id='-52' action='modify' timestamp='2010-03-15T09:31:53Z' visible='true'>
+    <nd ref='-6' />
+    <nd ref='-4' />
     <tag k='name' v='way 7.2' />
   </way>
-  <way id='-87' visible='true'>
-    <nd ref='-82' />
-    <nd ref='-86' />
-  </way>
-  <way id='-83' action='modify' visible='true'>
-    <nd ref='-81' />
-    <nd ref='-82' />
-    <tag k='name' v='way 7.1' />
-  </way>
-  <way id='-73' visible='true'>
-    <nd ref='-67' />
-    <nd ref='-69' />
-  </way>
-  <way id='-72' action='modify' visible='true'>
-    <nd ref='-67' />
-    <nd ref='-71' />
-    <tag k='name' v='way 6.2' />
-  </way>
-  <way id='-68' action='modify' visible='true'>
-    <nd ref='-66' />
-    <nd ref='-67' />
-    <tag k='name' v='way 6.1' />
-  </way>
-  <way id='-59' visible='true'>
-    <nd ref='-52' />
-    <nd ref='-54' />
-  </way>
-  <way id='-57' action='modify' visible='true'>
-    <nd ref='-52' />
-    <nd ref='-56' />
-    <tag k='name' v='way 5.2' />
-  </way>
-  <way id='-53' action='modify' visible='true'>
-    <nd ref='-51' />
-    <nd ref='-52' />
-    <tag k='name' v='way 5.1' />
-  </way>
-  <way id='-44' visible='true'>
-    <nd ref='-38' />
-    <nd ref='-40' />
-  </way>
-  <way id='-42' action='modify' visible='true'>
-    <nd ref='-40' />
-    <nd ref='-41' />
-    <tag k='name' v='way 4.2' />
-  </way>
-  <way id='-39' action='modify' visible='true'>
-    <nd ref='-37' />
-    <nd ref='-38' />
-    <tag k='name' v='way 4.1' />
-  </way>
-  <way id='-30' action='modify' visible='true'>
-    <nd ref='-26' />
-    <nd ref='-28' />
-    <tag k='name' v='Weg 3.2' />
-  </way>
-  <way id='-27' action='modify' visible='true'>
-    <nd ref='-25' />
-    <nd ref='-26' />
-    <tag k='name' v='Weg 3.1' />
-  </way>
-  <way id='-20' action='modify' timestamp='2010-03-09T09:06:53Z' visible='true'>
-    <nd ref='-12' />
-    <nd ref='-10' />
-    <tag k='name' v='Weg 1.1' />
-  </way>
-  <way id='-18' action='modify' timestamp='2010-03-09T09:06:53Z' visible='true'>
-    <nd ref='-10' />
-    <nd ref='-8' />
-    <tag k='name' v='Weg 1.2' />
-  </way>
-  <way id='-16' action='modify' timestamp='2010-03-09T09:06:53Z' visible='true'>
-    <nd ref='-6' />
-    <nd ref='-4' />
-    <tag k='name' v='Weg 2.1' />
-  </way>
-  <way id='-14' action='modify' timestamp='2010-03-09T09:06:53Z' visible='true'>
-    <nd ref='-4' />
-    <nd ref='-2' />
-    <tag k='name' v='Weg 2.2' />
-  </way>
-  <relation id='-96' visible='true'>
-    <member type='way' ref='-83' role='from' />
-    <member type='way' ref='-88' role='to' />
-    <member type='node' ref='-82' role='via' />
+  <relation id='-100' timestamp='2010-03-09T09:06:53Z' visible='true'>
+    <member type='way' ref='-84' role='from' />
+    <member type='way' ref='-86' role='to' />
+    <tag k='restriction' v='no_right_turn' />
+    <tag k='type' v='restriction' />
+  </relation>
+  <relation id='-98' timestamp='2010-03-09T09:06:53Z' visible='true'>
+    <member type='way' ref='-80' role='from' />
+    <member type='way' ref='-82' role='to' />
+    <tag k='restriction' v='no_left_turn' />
+    <tag k='type' v='restriction' />
+  </relation>
+  <relation id='-96' timestamp='2010-03-15T09:31:53Z' visible='true'>
+    <member type='way' ref='-78' role='from' />
+    <member type='way' ref='-76' role='to' />
+    <tag k='restriction' v='no_straight_on' />
+    <tag k='type' v='restriction' />
+  </relation>
+  <relation id='-94' timestamp='2010-03-15T09:31:53Z' visible='true'>
+    <member type='way' ref='-74' role='from' />
+    <member type='way' ref='-72' role='to' />
+    <member type='way' ref='-70' role='via' />
+    <tag k='restriction' v='no_u_turn' />
+    <tag k='type' v='restriction' />
+  </relation>
+  <relation id='-92' timestamp='2010-03-15T09:31:53Z' visible='true'>
+    <member type='way' ref='-68' role='from' />
+    <member type='way' ref='-66' role='to' />
+    <member type='node' ref='-22' role='via' />
+    <tag k='restriction' v='only_left_turn' />
+    <tag k='type' v='restriction' />
+  </relation>
+  <relation id='-90' timestamp='2010-03-15T09:31:53Z' visible='true'>
+    <member type='way' ref='-62' role='from' />
+    <member type='way' ref='-60' role='to' />
+    <member type='node' ref='-14' role='via' />
+    <tag k='restriction' v='only_right_turn' />
+    <tag k='type' v='restriction' />
+  </relation>
+  <relation id='-88' timestamp='2010-03-15T09:31:53Z' visible='true'>
+    <member type='way' ref='-56' role='from' />
+    <member type='way' ref='-52' role='to' />
+    <member type='node' ref='-6' role='via' />
     <tag k='restriction' v='only_straight_on' />
     <tag k='type' v='restriction' />
   </relation>
-  <relation id='-80' visible='true'>
-    <member type='way' ref='-68' role='from' />
-    <member type='way' ref='-72' role='to' />
-    <member type='node' ref='-67' role='via' />
-    <tag k='restriction' v='only_right_turn' />
-    <tag k='type' v='restriction' />
-  </relation>
-  <relation id='-65' visible='true'>
-    <member type='way' ref='-53' role='from' />
-    <member type='way' ref='-57' role='to' />
-    <member type='node' ref='-52' role='via' />
-    <tag k='restriction' v='only_left_turn' />
-    <tag k='type' v='restriction' />
-  </relation>
-  <relation id='-48' visible='true'>
-    <member type='way' ref='-39' role='from' />
-    <member type='way' ref='-42' role='to' />
-    <member type='way' ref='-44' role='via' />
-    <tag k='restriction' v='no_u_turn' />
-    <tag k='type' v='restriction' />
-  </relation>
-  <relation id='-36' visible='true'>
-    <member type='way' ref='-27' role='from' />
-    <member type='way' ref='-30' role='to' />
-    <tag k='restriction' v='no_straight_on' />
-    <tag k='type' v='restriction' />
-  </relation>
-  <relation id='-24' timestamp='2010-03-09T09:06:53Z' visible='true'>
-    <member type='way' ref='-20' role='from' />
-    <member type='way' ref='-18' role='to' />
-    <tag k='restriction' v='no_left_turn' />
-    <tag k='type' v='restriction' />
-  </relation>
-  <relation id='-22' timestamp='2010-03-09T09:06:53Z' visible='true'>
-    <member type='way' ref='-16' role='from' />
-    <member type='way' ref='-14' role='to' />
-    <tag k='restriction' v='no_right_turn' />
-    <tag k='type' v='restriction' />
-  </relation>
 </osm>
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/AbstractTurnRestrictionsListView.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/AbstractTurnRestrictionsListView.java	(revision 20484)
+++ 	(revision )
@@ -1,34 +1,0 @@
-package org.openstreetmap.josm.plugins.turnrestrictions;
-
-import javax.swing.JList;
-import javax.swing.JPanel;
-import javax.swing.event.ListSelectionListener;
-
-/**
- * The abstract base class for two views of turn restriction lists.
- * 
- * @see TurnRestrictionsInSelectionView
- * @see TurnRestrictionsInDatasetView
- *
- */
-abstract class AbstractTurnRestrictionsListView extends JPanel {
-	protected TurnRestrictionsListModel model;
-	protected JList lstTurnRestrictions;
-	
-	public TurnRestrictionsListModel getModel(){
-		return model;
-	}
-	
-	public JList getList() {
-		return lstTurnRestrictions;
-	}
-	
-	public void addListSelectionListener(ListSelectionListener listener) {
-		lstTurnRestrictions.addListSelectionListener(listener);
-	}
-	 
-	public void removeListSelectionListener(ListSelectionListener listener) {
-		lstTurnRestrictions.addListSelectionListener(listener);
-	}
-
-}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionListCellRenderer.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionListCellRenderer.java	(revision 20484)
+++ 	(revision )
@@ -1,221 +1,0 @@
-package org.openstreetmap.josm.plugins.turnrestrictions;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.Insets;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.swing.ImageIcon;
-import javax.swing.JLabel;
-import javax.swing.JList;
-import javax.swing.JPanel;
-import javax.swing.ListCellRenderer;
-import javax.swing.UIManager;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
-import org.openstreetmap.josm.data.osm.Relation;
-import org.openstreetmap.josm.data.osm.RelationMember;
-import org.openstreetmap.josm.data.osm.Way;
-import org.openstreetmap.josm.gui.DefaultNameFormatter;
-import org.openstreetmap.josm.gui.JMultilineLabel;
-import org.openstreetmap.josm.tools.ImageProvider;
-
-/**
- * This the cell renderer for turn restrictions in the turn restriction list
- * dialog.
- *
- */
-public class TurnRestrictionListCellRenderer extends JPanel implements ListCellRenderer{
-
-	/** the names of restriction types */
-	static private Set<String> RESTRICTION_TYPES = new HashSet<String>(
-			Arrays.asList(new String[] {
-					"no_left_turn",
-					"no_right_turn",
-					"no_straight_on",
-					"no_u_turn",
-					"only_left_turn",
-					"only_right_turn",
-					"only_straight_on"
-			})
-	);
-	
-	/** components used to render the turn restriction */
-	private JLabel icon;
-	private JLabel from;
-	private JLabel to;
-	
-	public TurnRestrictionListCellRenderer() {
-		build();
-	}
-
-	/**
-	 * Replies true if {@code restrictionType} is a valid restriction
-	 * type.
-	 * 
-	 * @param restrictionType the restriction type 
-	 * @return true if {@code restrictionType} is a valid restriction
-	 * type
-	 */
-	protected boolean isValidRestrictionType(String restrictionType) {
-		if (restrictionType == null) return false;
-		restrictionType = restrictionType.trim().toLowerCase();
-		return RESTRICTION_TYPES.contains(restrictionType);
-	}
-	
-	/**
-	 * Builds the icon name for a given restriction type 
-	 * 
-	 * @param restrictionType the restriction type 
-	 * @return the icon name 
-	 */
-	protected String buildImageName(String restrictionType) {
-		return "types/" + restrictionType;
-	}
-	
-	/**
-	 * Replies the icon for a given restriction type 
-	 * @param restrictionType the restriction type 
-	 * @return the icon 
-	 */
-	protected ImageIcon getIcon(String restrictionType) {
-		if (!isValidRestrictionType(restrictionType)) return null;
-		return ImageProvider.get(buildImageName(restrictionType));
-	}
- 	
-	/**
-	 * Builds the UI used to render turn restrictions 
-	 */
-	protected void build() {
-		setLayout(new GridBagLayout());
-		GridBagConstraints gc = new GridBagConstraints();
-		
-		// the turn restriction icon 		
-		gc.fill = GridBagConstraints.HORIZONTAL;
-		gc.weightx = 0.0;
-		gc.gridheight = 2;
-		gc.anchor = GridBagConstraints.CENTER;
-		gc.insets = new Insets(0,2,0,2);
-		add(icon = new JLabel(), gc);
-		
-		
-		// the name of the way with role "from"
-		gc.anchor = GridBagConstraints.NORTHWEST;
-		gc.gridx = 1;
-		gc.gridheight = 1;
-		gc.weightx = 0.0;
-		gc.insets = new Insets(0,0,0,0);
-		add(new JMultilineLabel("<html><strong>From:</strong></html>"), gc);
-		
-		gc.gridx = 2;
-		gc.weightx = 1.0; 
-		add(from = new JLabel(), gc);
-		
-		// the name of the way with role "to"
-		gc.anchor = GridBagConstraints.NORTHWEST;
-		gc.gridx = 1;
-		gc.gridy = 1;
-		gc.weightx = 0.0;
-		add(new JMultilineLabel("<html><strong>To:</strong></html>"), gc);
-		
-		gc.gridx = 2;
-		gc.weightx = 1.0;
-		add(to = new JLabel(), gc);
-	}
-
-	/**
-	 * Renders the icon for the turn restriction  
-	 * 
-	 * @param tr the turn restriction
-	 */
-	protected void renderIcon(Relation tr) {
-		String restrictionType = tr.get("restriction");
-		if (!isValidRestrictionType(restrictionType)) {
-			icon.setIcon(null);
-			return;
-		}
-		icon.setIcon(getIcon(restrictionType));
-	}
-
-	/**
-	 * Replies a way participating in this turn restriction in a given role
-	 * 
-	 * @param tr the turn restriction 
-	 * @param role the role (either "from" or "to")
-	 * @return the participating way; null, if no way is participating in this role
-	 */
-	private Way getParticipatingWay(Relation tr, String role){
-		for(RelationMember rm: tr.getMembers()){
-			if (rm.getRole().trim().toLowerCase().equals(role) && rm.getType().equals(OsmPrimitiveType.WAY)) {
-				return (Way)rm.getMember();
-			}
-		}
-		return null;
-	}
-	
-	protected void renderFrom(Relation tr) {
-		Way from = getParticipatingWay(tr, "from");
-		if (from == null) {
-			// FIXME: render as warning/error (red background?)
-			this.from.setText(tr("no participating way with role ''from''"));
-			return;
-		} 
-		this.from.setText(DefaultNameFormatter.getInstance().format(from));
-	}
-
-	protected void renderTo(Relation tr) {
-		Way to = getParticipatingWay(tr, "to");
-		if (to == null) {
-			// FIXME: render as warning/error (red background?)
-			this.to.setText(tr("no participating way with role ''to''"));
-			return;
-		} 
-		this.to.setText(DefaultNameFormatter.getInstance().format(to));
-	}
-
-	/**
-	 * Renders the foreground and background color depending on whether
-	 * the turn restriction is selected
-	 * 
-	 * @param isSelected true if the turn restriction is selected; false,
-	 * otherwise
-	 */
-	protected void renderColor(boolean isSelected) {
-		Color bg;
-		Color fg;
-		if (isSelected) {
-			bg = UIManager.getColor("List.selectionBackground");
-			fg = UIManager.getColor("List.selectionForeground");
-		} else {
-			bg = UIManager.getColor("background");
-			fg = UIManager.getColor("foreground");
-		}
-		setBackground(bg);
-		this.icon.setBackground(bg);
-		this.from.setBackground(bg);
-		this.to.setBackground(bg);
-		
-		setForeground(fg);
-		this.icon.setForeground(fg);
-		this.from.setForeground(fg);
-		this.to.setForeground(fg);
-	}
-		
-	public Component getListCellRendererComponent(JList list, Object value,
-			int index, boolean isSelected, boolean cellHasFocus) {
-
-		renderColor(isSelected);
-		Relation tr = (Relation)value;
-		renderIcon(tr);
-		renderFrom(tr);
-		renderTo(tr);		
-		return this;
-	}	
-}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionsInDatasetListModel.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionsInDatasetListModel.java	(revision 20484)
+++ 	(revision )
@@ -1,132 +1,0 @@
-package org.openstreetmap.josm.plugins.turnrestrictions;
-
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.logging.Logger;
-
-import javax.swing.DefaultListSelectionModel;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.Relation;
-import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
-import org.openstreetmap.josm.data.osm.event.DataChangedEvent;
-import org.openstreetmap.josm.data.osm.event.DataSetListener;
-import org.openstreetmap.josm.data.osm.event.NodeMovedEvent;
-import org.openstreetmap.josm.data.osm.event.PrimitivesAddedEvent;
-import org.openstreetmap.josm.data.osm.event.PrimitivesRemovedEvent;
-import org.openstreetmap.josm.data.osm.event.RelationMembersChangedEvent;
-import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
-import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
-import org.openstreetmap.josm.gui.MapView.EditLayerChangeListener;
-import org.openstreetmap.josm.gui.layer.OsmDataLayer;
-
-/**
- * This is the list model for the list of turn restrictions in the current data set.
- * 
- * The model is a {@see EditLayerChangeListener}. It initializes itself from the data set of
- * the current edit layer.
- * 
- * The model is a {@see DataSetListener}. It updates itself to reflect the list of turn
- * restrictions in the current data set. 
- *
- */
-public class TurnRestrictionsInDatasetListModel extends TurnRestrictionsListModel implements EditLayerChangeListener, DataSetListener {
-	private static final Logger logger = Logger.getLogger(TurnRestrictionsInDatasetListModel.class.getName());
-	
-	public TurnRestrictionsInDatasetListModel(
-			DefaultListSelectionModel selectionModel) {
-		super(selectionModel);
-	}
-	
-	/**
-	 * Filters the list of turn restrictions from a collection of OSM primitives.
-	 * 
-	 * @param primitives the primitives 
-	 * @return the list of turn restrictions 
-	 */
-	protected List<Relation> filterTurnRestrictions(Collection<? extends OsmPrimitive> primitives) {
-		List<Relation> ret = new LinkedList<Relation>();
-		if (primitives == null) return ret;
-		for(OsmPrimitive p: primitives){
-			if (!isTurnRestriction(p)) continue;
-			ret.add((Relation)p);
-		}
-		return ret;
-	}
-	
-	/* --------------------------------------------------------------------------- */
-	/* interface EditLayerChangeListener                                           */
-	/* --------------------------------------------------------------------------- */
-	public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) {
-		if (newLayer == null) {
-			setTurnRestrictions(null);
-			return;
-		}
-		List<Relation> turnRestrictions = new LinkedList<Relation>();
-		for (Relation r: newLayer.data.getRelations()) {
-			if (isValid(r) && isTurnRestriction(r)) {
-				turnRestrictions.add(r);
-			}
-		}
-		setTurnRestrictions(turnRestrictions);
-	}
-	
-	/* --------------------------------------------------------------------------- */
-	/* interface DataSetListener                                                   */
-	/* --------------------------------------------------------------------------- */	
-	public void dataChanged(DataChangedEvent event) {		
-		OsmDataLayer layer = Main.map.mapView.getEditLayer();
-		if (layer == null) {
-			setTurnRestrictions(null);
-		} else {
-			List<Relation> turnRestrictions = filterTurnRestrictions(layer.data.getRelations());
-			setTurnRestrictions(turnRestrictions);
-		}
-	}
-
-	public void primtivesAdded(PrimitivesAddedEvent event) {
-		List<Relation> turnRestrictions = filterTurnRestrictions(event.getPrimitives());
-		if (!turnRestrictions.isEmpty()) {
-			addTurnRestrictions(turnRestrictions);
-		}
-	}
-
-	public void primtivesRemoved(PrimitivesRemovedEvent event) {
-		List<Relation> turnRestrictions = filterTurnRestrictions(event.getPrimitives());
-		if (!turnRestrictions.isEmpty()) {
-			removeTurnRestrictions(turnRestrictions);
-		}
-	}
-
-	public void relationMembersChanged(RelationMembersChangedEvent event) {
-		List<Relation> turnRestrictions = filterTurnRestrictions(event.getPrimitives());
-		if (!turnRestrictions.isEmpty()) {
-			List<Relation> sel = getSelectedTurnRestrictions();
-			for(Relation tr: turnRestrictions) {	
-				// enforce a repaint of the respective turn restriction
-				int idx = getTurnRestrictionIndex(tr);
-				fireContentsChanged(this, idx,idx);
-			}
-			setSelectedTurnRestrictions(sel);
-		}
-	}
-
-	public void tagsChanged(TagsChangedEvent event) {
-		List<Relation> turnRestrictions = filterTurnRestrictions(event.getPrimitives());
-		if (!turnRestrictions.isEmpty()) {
-			List<Relation> sel = getSelectedTurnRestrictions();
-			for(Relation tr: turnRestrictions) {	
-				// enforce a repaint of the respective turn restriction
-				int idx = getTurnRestrictionIndex(tr);
-				fireContentsChanged(this, idx,idx);
-			}
-			setSelectedTurnRestrictions(sel);
-		}		
-	}
-
-	public void wayNodesChanged(WayNodesChangedEvent event) {/* ignore */}
-	public void nodeMoved(NodeMovedEvent event) {/* ignore */}
-	public void otherDatasetChange(AbstractDatasetChangedEvent event) {/* ignore */}
-}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionsInDatasetView.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionsInDatasetView.java	(revision 20484)
+++ 	(revision )
@@ -1,50 +1,0 @@
-package org.openstreetmap.josm.plugins.turnrestrictions;
-
-import java.awt.BorderLayout;
-
-import javax.swing.DefaultListSelectionModel;
-import javax.swing.JList;
-import javax.swing.JScrollPane;
-import javax.swing.ListSelectionModel;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.osm.event.DataSetListener;
-import org.openstreetmap.josm.data.osm.event.DatasetEventManager;
-import org.openstreetmap.josm.data.osm.event.DatasetEventManager.FireMode;
-import org.openstreetmap.josm.gui.MapView;
-import org.openstreetmap.josm.gui.MapView.EditLayerChangeListener;
-
-/**
- * This is the view for the list of turn restrictions in the current data set.
- */
-public class TurnRestrictionsInDatasetView extends AbstractTurnRestrictionsListView{	
-	protected void build() {
-		DefaultListSelectionModel selectionModel = new DefaultListSelectionModel();
-		model = new TurnRestrictionsInDatasetListModel(selectionModel);
-		lstTurnRestrictions = new JList(model);
-		lstTurnRestrictions.setSelectionModel(selectionModel);
-		lstTurnRestrictions.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
-		lstTurnRestrictions.setCellRenderer(new TurnRestrictionListCellRenderer());
-		
-		setLayout(new BorderLayout());
-		add(new JScrollPane(lstTurnRestrictions), BorderLayout.CENTER);
-	}
-
-	protected void registerAsListener() {
-		MapView.addEditLayerChangeListener((EditLayerChangeListener)model);
-		DatasetEventManager.getInstance().addDatasetListener((DataSetListener)model, FireMode.IN_EDT);
-		if (Main.main.getEditLayer() != null) {
-			model.setTurnRestrictions(Main.main.getEditLayer().data
-					.getRelations());
-		}
-	}
-
-	protected void unregisterAsListener() {
-		MapView.removeEditLayerChangeListener((EditLayerChangeListener)model);
-		DatasetEventManager.getInstance().removeDatasetListener((DataSetListener)model);
-	}
-
-	public TurnRestrictionsInDatasetView() {
-		build();
-	}
-}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionsInSelectionListModel.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionsInSelectionListModel.java	(revision 20484)
+++ 	(revision )
@@ -1,63 +1,0 @@
-package org.openstreetmap.josm.plugins.turnrestrictions;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.logging.Logger;
-
-import javax.swing.DefaultListSelectionModel;
-
-import org.openstreetmap.josm.data.SelectionChangedListener;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.Relation;
-import org.openstreetmap.josm.gui.MapView.EditLayerChangeListener;
-import org.openstreetmap.josm.gui.layer.OsmDataLayer;
-
-/**
- * This is the list model for the list of turn restrictions related to OSM
- * objects in the current selection.
- */
-public class TurnRestrictionsInSelectionListModel extends TurnRestrictionsListModel implements EditLayerChangeListener, SelectionChangedListener {
-	private static final Logger logger = Logger.getLogger(TurnRestrictionsInSelectionListModel.class.getName());
-	
-	public TurnRestrictionsInSelectionListModel(
-			DefaultListSelectionModel selectionModel) {
-		super(selectionModel);
-	}
-	
-	/**
-	 * Initializes the model with the turn restrictions the primitives in 
-	 * {@code selection} participate.
-	 * 
-	 * @param selection the collection of selected primitives
-	 */
-	public void initFromSelection(Collection<? extends OsmPrimitive> selection) {
-		Set<Relation> turnRestrictions = new HashSet<Relation>();
-		if (selection == null) return;
-		for (OsmPrimitive p: selection) {
-			for (OsmPrimitive parent: p.getReferrers()) {
-				if (isTurnRestriction(parent))
-					turnRestrictions.add((Relation)parent);
-			}
-		}
-		setTurnRestrictions(turnRestrictions);
-	}
-
-	/* --------------------------------------------------------------------------- */
-	/* interface EditLayerChangeListener                                           */
-	/* --------------------------------------------------------------------------- */
-	public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) {
-		if (newLayer == null) {
-			setTurnRestrictions(null);
-			return;
-		}
-		initFromSelection(newLayer.data.getSelected());
-	}
-	
-	/* --------------------------------------------------------------------------- */
-	/* interface SelectionChangedListener                                          */
-	/* --------------------------------------------------------------------------- */	
-	public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
-		initFromSelection(newSelection);
-	}
-}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionsInSelectionView.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionsInSelectionView.java	(revision 20484)
+++ 	(revision )
@@ -1,52 +1,0 @@
-package org.openstreetmap.josm.plugins.turnrestrictions;
-
-import java.awt.BorderLayout;
-
-import javax.swing.DefaultListSelectionModel;
-import javax.swing.JList;
-import javax.swing.JScrollPane;
-import javax.swing.ListSelectionModel;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.SelectionChangedListener;
-import org.openstreetmap.josm.data.osm.event.SelectionEventManager;
-import org.openstreetmap.josm.data.osm.event.DatasetEventManager.FireMode;
-import org.openstreetmap.josm.gui.MapView;
-import org.openstreetmap.josm.gui.MapView.EditLayerChangeListener;
-
-/**
- * This is the view for the list of turn restrictions related to objects in the 
- * current selection.
- * 
- */
-public class TurnRestrictionsInSelectionView extends AbstractTurnRestrictionsListView {
-
-	protected void build() {
-		DefaultListSelectionModel selectionModel = new DefaultListSelectionModel();
-		model = new TurnRestrictionsInSelectionListModel(selectionModel);
-		lstTurnRestrictions = new JList(model);
-		lstTurnRestrictions.setSelectionModel(selectionModel);
-		lstTurnRestrictions.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
-		lstTurnRestrictions.setCellRenderer(new TurnRestrictionListCellRenderer());
-		
-		setLayout(new BorderLayout());
-		add(new JScrollPane(lstTurnRestrictions), BorderLayout.CENTER);
-	}
-
-	protected void registerAsListener() {
-		MapView.addEditLayerChangeListener((EditLayerChangeListener)model);
-		SelectionEventManager.getInstance().addSelectionListener((SelectionChangedListener)model, FireMode.IN_EDT_CONSOLIDATED);
-		if (Main.main.getEditLayer() != null) {
-			model.setTurnRestrictions(Main.main.getEditLayer().data.getRelations());
-		}
-	}
-
-	protected void unregisterAsListener() {
-		MapView.removeEditLayerChangeListener((EditLayerChangeListener)model);
-		SelectionEventManager.getInstance().removeSelectionListener((SelectionChangedListener)model);
-	}
-
-	public TurnRestrictionsInSelectionView() {
-		build();
-	}
-}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionsListDialog.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionsListDialog.java	(revision 20484)
+++ 	(revision )
@@ -1,411 +1,0 @@
-package org.openstreetmap.josm.plugins.turnrestrictions;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.awt.BorderLayout;
-import java.awt.FlowLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
-import java.awt.event.MouseEvent;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.swing.AbstractAction;
-import javax.swing.JButton;
-import javax.swing.JCheckBox;
-import javax.swing.JList;
-import javax.swing.JPanel;
-import javax.swing.JPopupMenu;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.actions.AutoScaleAction;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.Relation;
-import org.openstreetmap.josm.data.osm.RelationMember;
-import org.openstreetmap.josm.gui.MapView;
-import org.openstreetmap.josm.gui.SideButton;
-import org.openstreetmap.josm.gui.MapView.EditLayerChangeListener;
-import org.openstreetmap.josm.gui.dialogs.ToggleDialog;
-import org.openstreetmap.josm.gui.dialogs.relation.RelationEditor;
-import org.openstreetmap.josm.gui.layer.OsmDataLayer;
-import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
-import org.openstreetmap.josm.tools.ImageProvider;
-
-/**
- * This is the toggle dialog for turn restrictions. The user can switch between
- * two lists of turn restrictions:
- * <ol>
- *   <li>the list of turn restrictions in the current data set</li>
- *   <li>the list of turn restrictions related to OSM objects in the current selection</li>
- * </ol>
- * 
- */
-public class TurnRestrictionsListDialog extends ToggleDialog{
-
-	/** checkbox for switching between the two list views */
-	private JCheckBox cbInSelectionOnly;
-	/** the view for the turn restrictions in the current data set */
-	private TurnRestrictionsInDatasetView pnlTurnRestrictionsInDataSet;
-	/** the view for the turn restrictions related to the current selection */
-	private TurnRestrictionsInSelectionView pnlTurnRestrictionsInSelection;
-	
-	/** three actions */
-	private NewAction actNew;
-	private EditAction actEdit;
-	private DeleteAction actDelete;	 
-	private SelectSelectedTurnRestrictions actSelectSelectedTurnRestrictions;
-	private ZoomToAction actZoomTo;
-	private SwitchListViewHandler switchListViewHandler;
-	
-	private AbstractTurnRestrictionsListView currentListView = null;
-	
-	/** the main content panel in this toggle dialog */
-	private JPanel pnlContent;
-	
-	@Override
-	public void showNotify() {
-		pnlTurnRestrictionsInDataSet.registerAsListener();		
-		pnlTurnRestrictionsInSelection.registerAsListener();
-		MapView.addEditLayerChangeListener(actNew);
-	}
-
-	@Override
-	public void hideNotify() {
-		pnlTurnRestrictionsInDataSet.unregisterAsListener();
-		pnlTurnRestrictionsInSelection.unregisterAsListener();
-		MapView.removeEditLayerChangeListener(actNew);
-	}
-
-	/**
-	 * Builds the panel with the checkbox for switching between the two
-	 * list views
-	 * 
-	 * @return the panel
-	 */
-	protected JPanel buildInSelectionOnlyTogglePanel(){
-		JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT,0,0));
-		pnl.setBorder(null);
-		pnl.add(cbInSelectionOnly = new JCheckBox(tr("Only participating in selection")));
-		cbInSelectionOnly.setToolTipText(tr(
-		   "<html>Select to display turn restrictions related to object in the current selection only.<br>"
-		 + "Deselect to display all turn restrictions in the current data set.</html>"));
-		return pnl;
-	}
-	
-	/**
-	 * Builds the panel with the action buttons 
-	 * 
-	 * @return the panel 
-	 */
-	protected JPanel buildCommandPanel() {
-		JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT,0,0));
-		pnl.setBorder(null);
-		pnl.add(new SideButton(actNew = new NewAction(), false /* don't show the name */));
-		pnl.add(new SideButton(actEdit = new EditAction(), false /* don't show the name */));
-		pnl.add(new SideButton(actDelete = new DeleteAction(), false /* don't show the name */));
-		
-		actSelectSelectedTurnRestrictions = new SelectSelectedTurnRestrictions();
-		actZoomTo = new ZoomToAction();
-		return pnl;
-	}
-	
-	/**
-	 * Builds the UI
-	 */
-	protected void build() {
-		pnlContent = new JPanel(new BorderLayout(0,0));
-		pnlContent.setBorder(null);
-		pnlContent.add(buildInSelectionOnlyTogglePanel(),  BorderLayout.NORTH);
-		pnlContent.add(buildCommandPanel(), BorderLayout.SOUTH);
-		
-		add(pnlContent, BorderLayout.CENTER);
-		
-		// create the two list views 
-		pnlTurnRestrictionsInDataSet = new TurnRestrictionsInDatasetView();
-		pnlTurnRestrictionsInSelection = new TurnRestrictionsInSelectionView();
-		
-		// wire the handler for switching between list views 
-		switchListViewHandler = new SwitchListViewHandler();
-		switchListViewHandler.activateListView(pnlTurnRestrictionsInDataSet);
-		cbInSelectionOnly.addItemListener(switchListViewHandler);
-		
-		// wire the popup menu launcher to the two turn restriction lists  
-		TurnRestrictionsPopupLauncher launcher = new TurnRestrictionsPopupLauncher();
-		pnlTurnRestrictionsInDataSet.getList().addMouseListener(launcher);
-		pnlTurnRestrictionsInSelection.getList().addMouseListener(launcher);
-	}
-	
-	/**
-	 * Constructor
-	 */
-	public TurnRestrictionsListDialog() {
-		super(
-				tr("Turn Restrictions"), 
-				"turnrestrictions",
-				tr("Display and manage turn restrictions in the current data set"),
-				null, // no shortcut
-				150   // default height
-		);
-		build();
-	}	
-	
-	/**
-	 * Switches between the two list view.
-	 */
-	class SwitchListViewHandler implements ItemListener {
-		public void activateListView(AbstractTurnRestrictionsListView view) {
-			if (currentListView != null) {
-				currentListView.removeListSelectionListener(actEdit);
-				currentListView.removeListSelectionListener(actDelete);
-				currentListView.removeListSelectionListener(actSelectSelectedTurnRestrictions);
-				currentListView.removeListSelectionListener(actZoomTo);
-				pnlContent.remove(currentListView);
-			}
-			pnlContent.add(view,BorderLayout.CENTER);
-			currentListView = view;						
-			view.addListSelectionListener(actEdit);
-			view.addListSelectionListener(actDelete);
-			view.addListSelectionListener(actSelectSelectedTurnRestrictions);
-			view.addListSelectionListener(actZoomTo);
-			actEdit.updateEnabledState();
-			actDelete.updateEnabledState();
-			actSelectSelectedTurnRestrictions.updateEnabledState();
-			actZoomTo.updateEnabledState();
-			currentListView.revalidate();
-			currentListView.repaint();
-		}
-
-		public void itemStateChanged(ItemEvent e) {
-			switch(e.getStateChange()) {
-			case ItemEvent.SELECTED:
-				activateListView(pnlTurnRestrictionsInSelection);
-				break;
-				
-			case ItemEvent.DESELECTED:		
-				activateListView(pnlTurnRestrictionsInDataSet);
-				break;
-			}
-		}
-	}
-	
-	 /**
-     * The edit action
-     *
-     */
-    class EditAction extends AbstractAction implements ListSelectionListener{
-        public EditAction() {
-            putValue(SHORT_DESCRIPTION,tr( "Open an editor for the selected turn restricion"));
-            putValue(SMALL_ICON, ImageProvider.get("dialogs", "edit"));
-            putValue(NAME, tr("Edit"));
-            setEnabled(false);
-        }
-        protected Collection<RelationMember> getMembersForCurrentSelection(Relation r) {
-            Collection<RelationMember> members = new HashSet<RelationMember>();
-            Collection<OsmPrimitive> selection = Main.map.mapView.getEditLayer().data.getSelected();
-            for (RelationMember member: r.getMembers()) {
-                if (selection.contains(member.getMember())) {
-                    members.add(member);
-                }
-            }
-            return members;
-        }
-
-        public void launchEditor(Relation toEdit) {
-            if (toEdit == null)
-                return;
-            RelationEditor.getEditor(Main.map.mapView.getEditLayer(),toEdit, getMembersForCurrentSelection(toEdit)).setVisible(true);
-        }
-
-        public void actionPerformed(ActionEvent e) {
-            if (!isEnabled())
-                return;
-            List<Relation> toEdit = currentListView.getModel().getSelectedTurnRestrictions();
-            if (toEdit.size() != 1) return;
-            launchEditor(toEdit.get(0));
-        }
-
-        public void updateEnabledState() {
-        	setEnabled(currentListView!= null && currentListView.getModel().getSelectedTurnRestrictions().size() == 1);
-        }
-        
-        public void valueChanged(ListSelectionEvent e) {
-            updateEnabledState();
-        }
-    }
-
-    /**
-     * The delete action
-     *
-     */
-    class DeleteAction extends AbstractAction implements ListSelectionListener {
-        class AbortException extends Exception {}
-
-        public DeleteAction() {
-            putValue(SHORT_DESCRIPTION,tr("Delete the selected turn restriction"));
-            putValue(SMALL_ICON, ImageProvider.get("dialogs", "delete"));
-            putValue(NAME, tr("Delete"));
-            setEnabled(false);
-        }
-
-        protected void deleteRelation(Relation toDelete) {
-            if (toDelete == null)
-                return;
-            org.openstreetmap.josm.actions.mapmode.DeleteAction.deleteRelation(
-                    Main.main.getEditLayer(),
-                    toDelete
-            );
-        }
-
-        public void actionPerformed(ActionEvent e) {
-            if (!isEnabled()) return;
-            List<Relation> toDelete = currentListView.getModel().getSelectedTurnRestrictions();
-            for (Relation r: toDelete) {
-                deleteRelation(r);
-            }
-        }
-        
-        public void updateEnabledState() {
-        	setEnabled(currentListView != null && !currentListView.getModel().getSelectedTurnRestrictions().isEmpty());
-        }
-
-        public void valueChanged(ListSelectionEvent e) {
-        	updateEnabledState();
-        }
-    }
-
-    /**
-     * The action for creating a new turn restriction
-     *
-     */
-    static class NewAction extends AbstractAction implements EditLayerChangeListener{
-        public NewAction() {
-            putValue(SHORT_DESCRIPTION,tr("Create a new turn restriction"));
-            putValue(SMALL_ICON, ImageProvider.get("new"));
-            putValue(NAME, tr("New"));
-            updateEnabledState();
-        }
-
-        public void run() {
-            RelationEditor.getEditor(Main.main.getEditLayer(),null, null).setVisible(true);
-        }
-
-        public void actionPerformed(ActionEvent e) {
-            run();
-        }
-
-        protected void updateEnabledState() {
-            setEnabled(Main.main != null && Main.main.getEditLayer() != null);
-        }
-
-		public void editLayerChanged(OsmDataLayer oldLayer,
-				OsmDataLayer newLayer) {
-            updateEnabledState();
-		}
-    }
-    
-    /**
-     * Sets the selection of the current data set to the currently selected 
-     * turn restrictions.
-     *
-     */
-    class SelectSelectedTurnRestrictions extends AbstractAction implements ListSelectionListener {
-        class AbortException extends Exception {}
-
-        public SelectSelectedTurnRestrictions() {
-            putValue(SHORT_DESCRIPTION,tr("Set the current JOSM selection to the selected turn restrictions"));
-            putValue(SMALL_ICON, ImageProvider.get("selectall"));
-            putValue(NAME, tr("Select in current data layer"));
-            setEnabled(false);
-        }
-
-        public void actionPerformed(ActionEvent e) {
-            if (!isEnabled()) return;
-            List<Relation> toSelect = currentListView.getModel().getSelectedTurnRestrictions();
-            if (toSelect.isEmpty()) return;
-            OsmDataLayer layer= Main.main.getEditLayer();
-            if (layer == null) return;
-            layer.data.setSelected(toSelect);
-        }
-        
-        public void updateEnabledState() {
-        	setEnabled(currentListView != null && !currentListView.getModel().getSelectedTurnRestrictions().isEmpty());
-        }
-
-        public void valueChanged(ListSelectionEvent e) {
-        	updateEnabledState();
-        }
-    }
-    
-    /**
-     * Sets the selection of the current data set to the currently selected 
-     * turn restrictions.
-     *
-     */
-    class ZoomToAction extends AbstractAction implements ListSelectionListener {
-        class AbortException extends Exception {}
-
-        public ZoomToAction() {
-            putValue(SHORT_DESCRIPTION,tr("Zoom to the currently selected turn restrictions"));
-            putValue(SMALL_ICON, ImageProvider.get("dialogs/autoscale/selection"));
-            putValue(NAME, tr("Zoom to"));
-            setEnabled(false);
-        }
-
-        public void actionPerformed(ActionEvent e) {
-            if (!isEnabled()) return;
-            List<Relation> toSelect = currentListView.getModel().getSelectedTurnRestrictions();
-            if (toSelect.isEmpty()) return;
-            OsmDataLayer layer= Main.main.getEditLayer();
-            if (layer == null) return;
-            layer.data.setSelected(toSelect);
-            new AutoScaleAction("selection").autoScale();
-        }
-        
-        public void updateEnabledState() {
-        	setEnabled(currentListView != null && !currentListView.getModel().getSelectedTurnRestrictions().isEmpty());
-        }
-
-        public void valueChanged(ListSelectionEvent e) {
-        	updateEnabledState();
-        }
-    }
-    
-    /**
-     * The launcher for the popup menu.
-     * 
-     */
-    class TurnRestrictionsPopupLauncher extends PopupMenuLauncher {
-        @Override
-        public void launch(MouseEvent evt) {
-            JList lst = currentListView.getList();
-            if (lst.getSelectedIndices().length == 0) {
-                int idx = lst.locationToIndex(evt.getPoint());
-                if (idx >=0) {
-                    lst.getSelectionModel().addSelectionInterval(idx, idx);
-                }
-            }
-            TurnRestrictionsPopupMenu popup = new TurnRestrictionsPopupMenu();
-            popup.show(lst, evt.getX(), evt.getY());
-        }
-    }
-
-    /**
-     * The popup menu 
-     *
-     */
-    class TurnRestrictionsPopupMenu extends JPopupMenu {
-        public TurnRestrictionsPopupMenu() {
-            add(actNew);
-            add(actEdit);
-            add(actDelete);
-            addSeparator();
-            add(actSelectSelectedTurnRestrictions);
-            add(actZoomTo);
-        }
-    }
-}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionsListModel.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionsListModel.java	(revision 20484)
+++ 	(revision )
@@ -1,232 +1,0 @@
-package org.openstreetmap.josm.plugins.turnrestrictions;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.swing.AbstractListModel;
-import javax.swing.DefaultListSelectionModel;
-
-import org.openstreetmap.josm.data.osm.NameFormatter;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.Relation;
-import org.openstreetmap.josm.gui.DefaultNameFormatter;
-
-/**
- * This is a list model for a list of turn restrictions.
- * 
- */
-public class TurnRestrictionsListModel extends AbstractListModel {
-    private final ArrayList<Relation> turnrestrictions = new ArrayList<Relation>();
-    private DefaultListSelectionModel selectionModel;
-
-    /**
-     * Creates the model
-     * 
-     * @param selectionModel the selection model used in the turn restriction list
-     */
-    public TurnRestrictionsListModel(DefaultListSelectionModel selectionModel) {
-        this.selectionModel = selectionModel;
-    }
-
-    /**
-     * Replies the turn restriction at position {@code idx} in the list.
-     * 
-     * @param idx the index 
-     * @return the turn restriction at position {@code idx} in the list.
-     */
-    public Relation getTurnRestriction(int idx) {
-        return turnrestrictions.get(idx);
-    }
-
-    /**
-     * Sorts the turn restrictions in this model 
-     */
-    public void sort() {
-        Collections.sort(
-                turnrestrictions,
-                new Comparator<Relation>() {
-                    NameFormatter formatter = DefaultNameFormatter.getInstance();
-
-                    public int compare(Relation r1, Relation r2) {
-                        return r1.getDisplayName(formatter).compareTo(r2.getDisplayName(formatter));
-                    }
-                }
-        );
-    }
-
-    protected boolean isValid(Relation r) {
-        return !r.isDeleted() && r.isVisible() && !r.isIncomplete();
-    }
-    
-    /**
-     * Replies true if the primitive {@code primitive} represents
-     * an OSM turn restriction.  
-     * 
-     * @param primitive the primitive 
-     * @return true if the primitive {@code primitive} represents
-     * an OSM turn restriction; false, otherwise
-     */
-    protected boolean isTurnRestriction(OsmPrimitive primitive) {
-    	if (primitive == null) return false;
-    	if (! (primitive instanceof Relation)) return false;
-    	String type = primitive.get("type");
-    	if (type == null || ! type.equals("restriction")) return false;
-    	return true;
-    }
-    
-    /**
-     * Populates the model with the turn restrictions in {@code turnrestrictions}.
-     * 
-     * @param turnrestrictions the turn restrictions 
-     */
-    public void setTurnRestrictions(Collection<Relation> turnrestrictions) {
-        List<Relation> sel =  getSelectedTurnRestrictions();
-        this.turnrestrictions.clear();
-        if (turnrestrictions == null) {
-            selectionModel.clearSelection();
-            fireContentsChanged(this,0,getSize());
-            return;
-        }
-        for (Relation r: turnrestrictions) {
-            if (isValid(r) && isTurnRestriction(r)) {
-                this.turnrestrictions.add(r);
-            }
-        }
-        sort();
-        fireIntervalAdded(this, 0, getSize());
-        setSelectedTurnRestrictions(sel);
-    }
-
-    /**
-     * Add all turn restrictions in <code>addedPrimitives</code> to the model for the
-     * relation list dialog
-     *
-     * @param addedPrimitives the collection of added primitives. May include nodes,
-     * ways, and relations.
-     */
-    public void addTurnRestrictions(Collection<? extends OsmPrimitive> addedPrimitives) {
-        boolean added = false;
-        for (OsmPrimitive p: addedPrimitives) {
-            if (! isTurnRestriction(p)) {
-                continue;
-            }
-
-            Relation r = (Relation)p;
-            if (!isValid(r)) continue;
-            if (turnrestrictions.contains(r)) {
-                continue;
-            }
-			turnrestrictions.add(r);
-			added = true;
-        }
-        if (added) {
-            List<Relation> sel = getSelectedTurnRestrictions();
-            sort();
-            fireIntervalAdded(this, 0, getSize());
-            setSelectedTurnRestrictions(sel);
-        }
-    }
-
-    /**
-     * Removes all turn restrictions in <code>removedPrimitives</code> from the model
-     *
-     * @param removedPrimitives the removed primitives. May include nodes, ways,
-     *   and relations
-     */
-    public void removeTurnRestrictions(Collection<? extends OsmPrimitive> removedPrimitives) {
-        if (removedPrimitives == null) return;
-        Set<Relation> removedTurnRestrictions = new HashSet<Relation>();
-        for (OsmPrimitive p: removedPrimitives) {
-        	if (!isTurnRestriction(p)) continue;
-            removedTurnRestrictions.add((Relation)p);
-        }
-        if (removedTurnRestrictions.isEmpty())return;
-        int size = turnrestrictions.size();
-        turnrestrictions.removeAll(removedTurnRestrictions);
-        if (size != turnrestrictions.size()) {
-            List<Relation> sel = getSelectedTurnRestrictions();
-            sort();
-            fireContentsChanged(this, 0, getSize());
-            setSelectedTurnRestrictions(sel);
-        }
-    }
-
-    public Object getElementAt(int index) {
-        return turnrestrictions.get(index);
-    }
-
-    public int getSize() {
-        return turnrestrictions.size();
-    }
-
-    /**
-     * Replies the list of selected, non-new relations. Empty list,
-     * if there are no selected, non-new relations.
-     *
-     * @return the list of selected, non-new relations.
-     */
-    public List<Relation> getSelectedNonNewRelations() {
-        ArrayList<Relation> ret = new ArrayList<Relation>();
-        for (int i=0; i<getSize();i++) {
-            if (!selectionModel.isSelectedIndex(i)) {
-                continue;
-            }
-            if (turnrestrictions.get(i).isNew()) {
-                continue;
-            }
-            ret.add(turnrestrictions.get(i));
-        }
-        return ret;
-    }
-
-    /**
-     * Replies the list of selected turn restrictions. Empty list,
-     * if there are no selected turn restrictions.
-     *
-     * @return the list of selected turn restrictions
-     */
-    public List<Relation> getSelectedTurnRestrictions() {
-        ArrayList<Relation> ret = new ArrayList<Relation>();
-        for (int i=0; i<getSize();i++) {
-            if (!selectionModel.isSelectedIndex(i)) {
-                continue;
-            }
-            ret.add(turnrestrictions.get(i));
-        }
-        return ret;
-    }
-
-    /**
-     * Sets the selected turn restrictions
-     *
-     * @return sel the list of selected turn restrictions
-     */
-    public void setSelectedTurnRestrictions(List<Relation> sel) {
-        selectionModel.clearSelection();
-        if (sel == null || sel.isEmpty())
-            return;
-        for (Relation r: sel) {
-            int i = turnrestrictions.indexOf(r);
-            if (i<0) {
-                continue;
-            }
-            selectionModel.addSelectionInterval(i,i);
-        }
-    }
-
-    /**
-     * Returns the index of a turn restriction 
-     *
-     * @return index of relation (-1, if not found)
-     */
-    public int getTurnRestrictionIndex(Relation tr) {
-        int i = turnrestrictions.indexOf(tr);
-        if (i<0)return -1;
-        return i;
-    }
-}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionsPlugin.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionsPlugin.java	(revision 20484)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionsPlugin.java	(revision 20489)
@@ -5,4 +5,5 @@
 import org.openstreetmap.josm.plugins.Plugin;
 import org.openstreetmap.josm.plugins.PluginInformation;
+import org.openstreetmap.josm.plugins.turnrestrictions.list.TurnRestrictionsListDialog;
 import org.openstreetmap.josm.plugins.turnrestrictions.preferences.PreferenceEditor;
 
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/dnd/PrimitiveIdListProvider.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/dnd/PrimitiveIdListProvider.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/dnd/PrimitiveIdListProvider.java	(revision 20489)
@@ -0,0 +1,14 @@
+package org.openstreetmap.josm.plugins.turnrestrictions.dnd;
+
+import java.util.List;
+
+import org.openstreetmap.josm.data.osm.PrimitiveId;;
+public interface PrimitiveIdListProvider {
+	/**
+	 * Replies the list of currently selected primitive IDs. Replies an empty list if no primitive IDs
+	 * are selected.
+	 * 
+	 * @return the list of currently selected primitive IDs
+	 */
+	List<PrimitiveId> getSelectedPrimitiveIds();
+}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/dnd/PrimitiveIdListTransferHandler.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/dnd/PrimitiveIdListTransferHandler.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/dnd/PrimitiveIdListTransferHandler.java	(revision 20489)
@@ -0,0 +1,61 @@
+package org.openstreetmap.josm.plugins.turnrestrictions.dnd;
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.util.logging.Logger;
+
+import javax.swing.JComponent;
+import javax.swing.TransferHandler;
+
+import org.openstreetmap.josm.tools.CheckParameterUtil;
+
+/**
+ * PrimitiveIdListTransferHandler is a transfer handler for component which 
+ * provide and/or accept a list of {@see PrimitiveId} via copy/paste or
+ * drag-and-drop.
+ * 
+ * It creates a {@see Transferable} by retrieving the list of primitive IDs
+ * from a {@see PrimitiveIdListProvider}.
+ * 
+ */
+public class PrimitiveIdListTransferHandler extends TransferHandler {
+	static private final Logger logger = Logger.getLogger(PrimitiveIdListTransferHandler.class.getName());
+	private PrimitiveIdListProvider provider;
+	
+	/**
+	 * Creates the transfer handler 
+	 * 
+	 * @param provider the provider of the primitive IDs. Must not be null.
+	 * @throws IllegalArgumentException thrown if provider is null.
+	 */
+	public PrimitiveIdListTransferHandler(PrimitiveIdListProvider provider) throws IllegalArgumentException{
+		CheckParameterUtil.ensureParameterNotNull(provider, "provider");
+		this.provider = provider;
+	}
+
+	/**
+	 * Replies true if {@code transferFlavors} includes the data flavor {@see PrimitiveIdTransferable#PRIMITIVE_ID_LIST_FLAVOR}.
+
+	 * @param transferFlavors an array of transferFlavors
+	 * @return
+	 */
+	protected boolean isSupportedFlavor(DataFlavor[] transferFlavors) {
+		for (DataFlavor df: transferFlavors) {
+			if (df.equals(PrimitiveIdTransferable.PRIMITIVE_ID_LIST_FLAVOR)) return true;
+		}
+		return false;
+	}
+	
+	protected Transferable createTransferable(JComponent c) {
+		return new PrimitiveIdTransferable(provider.getSelectedPrimitiveIds());			
+	}
+
+	public int getSourceActions(JComponent c) {
+		return COPY;
+	}
+
+	@Override
+	public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
+		return isSupportedFlavor(transferFlavors);	
+	}	
+}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/dnd/PrimitiveIdTransferable.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/dnd/PrimitiveIdTransferable.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/dnd/PrimitiveIdTransferable.java	(revision 20489)
@@ -0,0 +1,101 @@
+package org.openstreetmap.josm.plugins.turnrestrictions.dnd;
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.openstreetmap.josm.data.osm.PrimitiveId;
+import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
+
+/**
+ * To be used for Drag-and-Drop of a set of {@see PrimitiveId}s between
+ * two components. 
+ *
+ */
+public class PrimitiveIdTransferable implements Transferable{
+	
+	/** the data flower for the set of of primitive ids */
+	static public final DataFlavor PRIMITIVE_ID_LIST_FLAVOR = 
+		new DataFlavor(Set.class, "a set of OSM primitive ids");
+	
+	/** 
+	 * this transferable supports two flavors: (1) {@see #PRIMITIVE_ID_LIST_FLAVOR} and
+	 * (2) {@see DataFlavor#stringFlavor}.
+	 * 
+	 * See also {@see #getPrimitiveIds()} and {@see #getAsString()}
+	 */
+	static public final DataFlavor[] SUPPORTED_FLAVORS = new DataFlavor[] {
+		PRIMITIVE_ID_LIST_FLAVOR,
+		DataFlavor.stringFlavor
+	};
+
+	
+	private List<PrimitiveId> ids = new ArrayList<PrimitiveId>();
+	
+	/**
+	 * Creates a transferable from a collection of {@see PrimitiveId}s
+	 * 
+	 * @param ids
+	 */
+	public PrimitiveIdTransferable(List<PrimitiveId> ids) {
+		if (ids == null) return;
+		for(PrimitiveId id: ids) {
+			this.ids.add(new SimplePrimitiveId(id.getUniqueId(), id.getType()));
+		}
+	}
+	
+	/**
+	 * If flavor is {@see #PRIMITIVE_ID_SET_FLAVOR}, replies a the list of
+	 * transferred {@see PrimitiveId}s 
+	 * 
+	 * If flavor is {@see DataFlavor#stringFlavor}, replies a string representation
+	 * of the list of transferred {@see PrimitiveId}s
+	 */
+	public Object getTransferData(DataFlavor flavor)
+			throws UnsupportedFlavorException, IOException {
+		if (PRIMITIVE_ID_LIST_FLAVOR.equals(flavor)) {
+			return getPrimitiveIds();
+		} else if (DataFlavor.stringFlavor.equals(flavor)) {
+			return getAsString();
+		}
+		throw new UnsupportedFlavorException(flavor);
+	}
+	
+	/**
+	 * Replies the list of OSM primitive ids
+	 * 
+	 * @return the list of OSM primitive ids
+	 */
+	public List<PrimitiveId> getPrimitiveIds() {
+		return ids;
+	}
+	
+	/**
+	 * Replies a string representation of the list of OSM primitive ids
+	 *  
+	 * @return a string representation of the list of OSM primitive ids
+	 */
+	public String getAsString() {
+		StringBuffer sb = new StringBuffer();
+		for(PrimitiveId id: ids) {
+			if (sb.length() > 0) sb.append(",");
+			sb.append(id.getType().getAPIName()).append("/").append(id.getUniqueId());
+		}
+		return sb.toString();
+	}
+
+	public DataFlavor[] getTransferDataFlavors() {
+		return SUPPORTED_FLAVORS;
+	}
+
+	public boolean isDataFlavorSupported(DataFlavor flavor) {
+		for(DataFlavor df: SUPPORTED_FLAVORS) {
+			if (df.equals(flavor)) return true;
+		}
+		return false;
+	}			
+}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/BasicEditorPanel.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/BasicEditorPanel.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/BasicEditorPanel.java	(revision 20489)
@@ -0,0 +1,102 @@
+package org.openstreetmap.josm.plugins.turnrestrictions.editor;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+
+import javax.swing.BorderFactory;
+import javax.swing.DefaultListSelectionModel;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+
+import org.openstreetmap.josm.tools.CheckParameterUtil;
+
+/**
+ * BasicEditorPanel provides a UI for editing the basic elements of a turn restriction,
+ * i.e. its restriction type, the from, the to, and the via objects.
+ * 
+ *
+ */
+public class BasicEditorPanel extends JPanel {
+
+	/** the turn restriction model */
+	private TurnRestrictionEditorModel model;
+	
+	/**
+	 * builds the UI
+	 */
+	protected void build() {
+		setLayout(new GridBagLayout());
+		GridBagConstraints gc = new GridBagConstraints();
+		gc.anchor = GridBagConstraints.WEST;
+		gc.fill = GridBagConstraints.HORIZONTAL;
+		gc.weightx = 0.0;
+		
+		// the editor for selecting the 'from' leg
+	    gc.insets = new Insets(0,0,5,5);	
+	    add(new JLabel("Type:"), gc);
+	    
+	    gc.gridx = 1;
+	    gc.weightx = 1.0;
+	    add(new TurnRestrictionComboBox(new TurnRestrictionComboBoxModel(model)), gc);
+
+		// the editor for selecting the 'from' leg
+	    gc.gridx = 0;
+	    gc.gridy = 1;	
+	    gc.weightx = 0.0;
+	    add(new JLabel("From:"), gc);
+	    
+	    gc.gridx = 1;
+	    gc.weightx = 1.0;
+	    add(new TurnRestrictionLegEditor(model, TurnRestrictionLegRole.FROM),gc);
+
+	    // the editor for selecting the 'to' leg
+	    gc.gridx = 0;
+	    gc.gridy = 2;
+		gc.weightx = 0.0;
+	    gc.insets = new Insets(0,0,5,5);	
+	    add(new JLabel("To:"), gc);
+	    
+	    gc.gridx = 1;
+	    gc.weightx = 1.0;
+	    add(new TurnRestrictionLegEditor(model, TurnRestrictionLegRole.TO),gc);
+	    
+	    // the editor for selecting the 'vias' 
+	    gc.gridx = 0;
+	    gc.gridy = 3;
+		gc.weightx = 0.0;
+	    gc.insets = new Insets(0,0,5,5);	
+	    add(new JLabel("Vias:"), gc);
+	    
+	    gc.gridx = 1;
+	    gc.weightx = 1.0;
+	    DefaultListSelectionModel selectionModel = new DefaultListSelectionModel();
+	    add(new JScrollPane(new ViaList(new ViaListModel(model, selectionModel), selectionModel)),gc);
+	    
+	    // just a filler - grabs remaining space 
+	    gc.gridx = 0;
+	    gc.gridy = 4;
+	    gc.gridwidth = 2;
+	    gc.weighty = 1.0;
+	    gc.fill = GridBagConstraints.BOTH;
+	    add(new JPanel(), gc);
+	   	    
+	    setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+	}
+	
+	
+	/**
+	 * Creates the panel. 
+	 * 
+	 * @param model the editor model. Must not be null.
+	 * @throws IllegalArgumentException thrown if model is null
+	 */
+	public BasicEditorPanel(TurnRestrictionEditorModel model) {
+		CheckParameterUtil.ensureParameterNotNull(model, "model");
+		this.model = model;
+		build();
+	}
+	
+	
+}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/JosmSelectionListModel.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/JosmSelectionListModel.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/JosmSelectionListModel.java	(revision 20489)
@@ -0,0 +1,283 @@
+package org.openstreetmap.josm.plugins.turnrestrictions.editor;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import javax.swing.AbstractListModel;
+import javax.swing.DefaultListSelectionModel;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.SelectionChangedListener;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
+import org.openstreetmap.josm.data.osm.PrimitiveId;
+import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
+import org.openstreetmap.josm.data.osm.event.DataChangedEvent;
+import org.openstreetmap.josm.data.osm.event.DataSetListener;
+import org.openstreetmap.josm.data.osm.event.NodeMovedEvent;
+import org.openstreetmap.josm.data.osm.event.PrimitivesAddedEvent;
+import org.openstreetmap.josm.data.osm.event.PrimitivesRemovedEvent;
+import org.openstreetmap.josm.data.osm.event.RelationMembersChangedEvent;
+import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
+import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
+import org.openstreetmap.josm.gui.DefaultNameFormatter;
+import org.openstreetmap.josm.gui.MapView.EditLayerChangeListener;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.plugins.turnrestrictions.dnd.PrimitiveIdListProvider;
+import org.openstreetmap.josm.tools.CheckParameterUtil;
+
+/**
+ * JosmSelectionListModel is the model for a list which displays the currently selected 
+ * objects in the current edit layer.
+ * 
+ */
+public class JosmSelectionListModel extends AbstractListModel implements EditLayerChangeListener, SelectionChangedListener, DataSetListener, PrimitiveIdListProvider{
+	static private final Logger logger = Logger.getLogger(JosmSelectionListModel.class.getName());
+	
+    private final List<OsmPrimitive> selection = new ArrayList<OsmPrimitive>();
+    private DefaultListSelectionModel selectionModel;
+    private DataSet dataSet;
+
+    /**
+     * Constructor
+     * 
+     * @param selectionModel the selection model used in the list. Must not be null.
+     * @param dataSet the dataset this model is displaying the selection from. Must not be null.
+     * @throws IllegalArgumentException thrown if {@code selectionModel} is null
+     */
+    public JosmSelectionListModel(DataSet dataSet, DefaultListSelectionModel selectionModel) {
+    	CheckParameterUtil.ensureParameterNotNull(selectionModel, "selectionModel");
+    	CheckParameterUtil.ensureParameterNotNull(dataSet, "dataSet");
+    	this.dataSet = dataSet;
+        this.selectionModel = selectionModel;
+        setJOSMSelection(dataSet.getSelected());
+    }
+
+    public Object getElementAt(int index) {
+        return selection.get(index);
+    }
+
+    public int getSize() {
+        return selection.size();
+    }
+
+    /**
+     * Replies the collection of OSM primitives currently selected in the view
+     * of this model
+     * 
+     * @return the selected primitives
+     */
+    public Collection<OsmPrimitive> getSelected() {
+        Set<OsmPrimitive> sel = new HashSet<OsmPrimitive>();
+        for(int i=0; i< getSize();i++) {
+            if (selectionModel.isSelectedIndex(i)) {
+                sel.add(selection.get(i));
+            }
+        }
+        return sel;
+    }
+
+    /**
+     * Sets the OSM primitives to be selected in the view of this model
+     * 
+     * @param sel the collection of primitives to select
+     */
+    public void setSelected(Collection<OsmPrimitive> sel) {
+        selectionModel.clearSelection();
+        if (sel == null) return;
+        for (OsmPrimitive p: sel){
+            int i = selection.indexOf(p);
+            if (i >= 0){
+                selectionModel.addSelectionInterval(i, i);
+            }
+        }
+    }
+
+    @Override
+    protected void fireContentsChanged(Object source, int index0, int index1) {
+        Collection<OsmPrimitive> sel = getSelected();
+        super.fireContentsChanged(source, index0, index1);
+        setSelected(sel);
+    }
+
+    /**
+     * Sets the collection of currently selected OSM objects
+     * 
+     * @param selection the collection of currently selected OSM objects
+     */
+    public void setJOSMSelection(Collection<? extends OsmPrimitive> selection) {
+    	Collection<OsmPrimitive> sel = getSelected();
+        this.selection.clear();
+        if (selection == null) {
+            fireContentsChanged(this, 0, getSize());
+            return;
+        }
+        this.selection.addAll(selection);
+        sort();
+        fireContentsChanged(this, 0, getSize());       
+        setSelected(sel);
+    }
+
+    /**
+     * Sorts the primitives in the list
+     */
+    public void sort() {
+        Collections.sort(this.selection,new OsmPrimitiveComparator());
+    }
+
+    /**
+     * Triggers a refresh of the view for all primitives in {@code toUpdate}
+     * which are currently displayed in the view
+     * 
+     * @param toUpdate the collection of primitives to update
+     */
+    public void update(Collection<? extends OsmPrimitive> toUpdate) {
+        if (toUpdate == null) return;
+        if (toUpdate.isEmpty()) return;
+        Collection<OsmPrimitive> sel = getSelected();
+        for (OsmPrimitive p: toUpdate){
+            int i = selection.indexOf(p);
+            if (i >= 0) {
+                super.fireContentsChanged(this, i,i);
+            }
+        }
+        setSelected(sel);
+    }
+
+    /* ------------------------------------------------------------------------ */
+    /* interface EditLayerChangeListener                                        */
+    /* ------------------------------------------------------------------------ */
+    public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) {
+        if (newLayer == null) {
+        	// don't show a JOSM selection if we don't have a data layer 
+            setJOSMSelection(null);
+        } else if (newLayer.data != dataSet){
+        	// don't show a JOSM selection if this turn restriction editor doesn't
+        	// manipulate data in the current data layer
+        	setJOSMSelection(null);
+        } else {
+            setJOSMSelection(newLayer.data.getSelected());
+        }
+    }
+
+    /* ------------------------------------------------------------------------ */
+    /* interface SelectionChangeListener                                        */
+    /* ------------------------------------------------------------------------ */
+    public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
+    	// only update the JOSM selection if it is changed in the same data layer
+    	// this turn restriction editor is working on
+    	OsmDataLayer layer = Main.main.getEditLayer();
+    	if(layer == null) return;
+    	if (layer.data != dataSet) return;
+        setJOSMSelection(newSelection);
+    }
+
+    /* ------------------------------------------------------------------------ */
+    /* interface DataSetListener                                                */
+    /* ------------------------------------------------------------------------ */
+    public void dataChanged(DataChangedEvent event) {
+        if (event.getDataset() != dataSet) return;
+        fireContentsChanged(this, 0, getSize());
+    }
+
+    public void nodeMoved(NodeMovedEvent event) {
+        if (event.getDataset() != dataSet) return;
+        // may influence the display name of primitives, update the data
+    	update(event.getPrimitives());
+    }
+
+    public void otherDatasetChange(AbstractDatasetChangedEvent event) {
+        if (event.getDataset() != dataSet) return;
+        // may influence the display name of primitives, update the data
+        update(event.getPrimitives());
+    }
+
+    public void relationMembersChanged(RelationMembersChangedEvent event) {
+        if (event.getDataset() != dataSet) return;
+        // may influence the display name of primitives, update the data
+        update(event.getPrimitives());
+    }
+
+    public void tagsChanged(TagsChangedEvent event) {
+        if (event.getDataset() != dataSet) return;
+        // may influence the display name of primitives, update the data
+        update(event.getPrimitives());
+    }
+
+    public void wayNodesChanged(WayNodesChangedEvent event) {
+        if (event.getDataset() != dataSet) return;
+        // may influence the display name of primitives, update the data
+        update(event.getPrimitives());
+    }
+
+    public void primtivesAdded(PrimitivesAddedEvent event) {/* ignored - handled by SelectionChangeListener */}
+    public void primtivesRemoved(PrimitivesRemovedEvent event) {/* ignored - handled by SelectionChangeListener*/}
+  
+    /* ------------------------------------------------------------------------ */
+    /* interface PrimitiveIdListProvider                                        */
+    /* ------------------------------------------------------------------------ */
+	public List<PrimitiveId> getSelectedPrimitiveIds() {
+		List<PrimitiveId> ret = new ArrayList<PrimitiveId>(getSelected().size());
+		for(OsmPrimitive p: getSelected()) {
+			ret.add(p.getPrimitiveId());
+		}
+		return ret;
+	}
+	
+	/**
+	 * The comparator used when sorting the elements in this model
+	 *
+	 */
+	static private class OsmPrimitiveComparator implements Comparator<OsmPrimitive> {
+        final private HashMap<Object, String> cache= new HashMap<Object, String>();
+        final private DefaultNameFormatter df  = DefaultNameFormatter.getInstance();
+
+        private String cachedName(OsmPrimitive p) {
+            String name = cache.get(p);
+            if (name == null) {
+                name = p.getDisplayName(df);
+                cache.put(p, name);
+            }
+            return name;
+        }
+
+        private int compareName(OsmPrimitive a, OsmPrimitive b) {
+            String an = cachedName(a);
+            String bn = cachedName(b);
+            // make sure display names starting with digits are the end of the
+            // list
+            if (Character.isDigit(an.charAt(0)) && Character.isDigit(bn.charAt(0)))
+                return an.compareTo(bn);
+            else if (Character.isDigit(an.charAt(0)) && !Character.isDigit(bn.charAt(0)))
+                return 1;
+            else if (!Character.isDigit(an.charAt(0)) && Character.isDigit(bn.charAt(0)))
+                return -1;
+            return an.compareTo(bn);
+        }
+
+        private int compareType(OsmPrimitive a, OsmPrimitive b) {
+            // show ways before relations, then nodes
+            //
+            if (a.getType().equals(b.getType())) return 0;
+            if (a.getType().equals(OsmPrimitiveType.WAY)) return -1;
+            if (a.getType().equals(OsmPrimitiveType.NODE)) return 1;
+            // a is a relation
+            if (b.getType().equals(OsmPrimitiveType.WAY)) return 1;
+            // b is a node
+            return -1;
+        }
+        public int compare(OsmPrimitive a, OsmPrimitive b) {
+            if (a.getType().equals(b.getType()))
+                return compareName(a, b);
+            return compareType(a, b);
+        }
+    }
+}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/JosmSelectionPanel.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/JosmSelectionPanel.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/JosmSelectionPanel.java	(revision 20489)
@@ -0,0 +1,146 @@
+package org.openstreetmap.josm.plugins.turnrestrictions.editor;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.BorderLayout;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.event.ActionEvent;
+import java.awt.event.MouseEvent;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.BorderFactory;
+import javax.swing.DefaultListSelectionModel;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JScrollPane;
+import javax.swing.ListSelectionModel;
+import javax.swing.TransferHandler;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.event.DatasetEventManager;
+import org.openstreetmap.josm.data.osm.event.SelectionEventManager;
+import org.openstreetmap.josm.data.osm.event.DatasetEventManager.FireMode;
+import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
+import org.openstreetmap.josm.plugins.turnrestrictions.dnd.PrimitiveIdListProvider;
+import org.openstreetmap.josm.plugins.turnrestrictions.dnd.PrimitiveIdListTransferHandler;
+import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Shortcut;
+
+/**
+ * This panels displays the objects currently selected in the current
+ * JOSM edit layer.
+ *
+ */
+public class JosmSelectionPanel extends JPanel {
+	/**  the list view */
+	private JList lstSelection;
+	/** the model managing the selection */
+	private JosmSelectionListModel model;
+	
+	private CopyAction actCopy;
+	private TransferHandler transferHandler;
+	
+	/**
+	 * builds the UI for the panel 
+	 */
+	protected void build(DataSet ds) {
+		setLayout(new BorderLayout());
+		DefaultListSelectionModel selectionModel = new DefaultListSelectionModel();
+		model = new JosmSelectionListModel(ds,selectionModel);
+		lstSelection = new JList(model);
+		lstSelection.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+		lstSelection.setSelectionModel(selectionModel);
+		lstSelection.setCellRenderer(new OsmPrimitivRenderer());
+		lstSelection.setTransferHandler(transferHandler = new JosmSelectionTransferHandler(model));
+		lstSelection.setDragEnabled(true);
+		
+		add(new JScrollPane(lstSelection), BorderLayout.CENTER);
+		add(new JLabel(tr("Selection")), BorderLayout.NORTH);
+		
+		setBorder(BorderFactory.createEmptyBorder(5,5,5,5));		
+		actCopy = new CopyAction();
+		lstSelection.addMouseListener(new PopupLauncher());
+	}
+	
+	/**
+	 * Creates the JOSM selection panel for the selection in a data set. 
+	 * 
+	 * @param ds the dataset. Must not be null.
+	 * @exception IllegalArgumentException thrown if ds is null
+	 */
+	public JosmSelectionPanel(DataSet ds) throws IllegalArgumentException{
+		CheckParameterUtil.ensureParameterNotNull(ds, "ds");
+		build(ds); 
+	}
+	
+	/**
+	 * wires the UI as listener to global event sources 
+	 */
+	public void wireListeners() {
+		MapView.addEditLayerChangeListener(model);
+		DatasetEventManager.getInstance().addDatasetListener(model, FireMode.IN_EDT);
+		SelectionEventManager.getInstance().addSelectionListener(model, FireMode.IN_EDT_CONSOLIDATED);
+	}
+	
+	/**
+	 * removes the UI as listener to global event sources 
+	 */
+	public void unwireListeners() {
+		MapView.removeEditLayerChangeListener(model);
+		DatasetEventManager.getInstance().removeDatasetListener(model);
+		SelectionEventManager.getInstance().removeSelectionListener(model);		
+	}
+	
+	class PopupLauncher extends PopupMenuLauncher {
+		@Override
+		public void launch(MouseEvent evt) {
+			new PopupMenu().show(lstSelection, evt.getX(), evt.getY());
+		}		
+	}
+	
+	class PopupMenu extends JPopupMenu {
+		public PopupMenu() {
+			JMenuItem item = add(actCopy);
+			item.setTransferHandler(transferHandler);
+			actCopy.setEnabled(!model.getSelected().isEmpty());
+		}
+	}
+
+	class CopyAction extends AbstractAction {
+		private Action delegate;
+		
+		public CopyAction(){
+			putValue(NAME, tr("Copy"));
+			putValue(SHORT_DESCRIPTION, tr("Copy to the clipboard"));
+			putValue(SMALL_ICON, ImageProvider.get("copy"));
+			putValue(ACCELERATOR_KEY, Shortcut.getCopyKeyStroke());
+			delegate = lstSelection.getActionMap().get("copy");
+		}
+
+		public void actionPerformed(ActionEvent e) {
+			delegate.actionPerformed(e);
+		}
+	}
+	
+	static private class JosmSelectionTransferHandler extends PrimitiveIdListTransferHandler {
+		public JosmSelectionTransferHandler(PrimitiveIdListProvider provider) {
+			super(provider);
+		}
+
+		@Override
+		public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
+			// the JOSM selection list is read-only. Don't allow to drop or paste
+			// data on it
+			return false;
+		}
+	}
+}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionComboBox.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionComboBox.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionComboBox.java	(revision 20489)
@@ -0,0 +1,28 @@
+package org.openstreetmap.josm.plugins.turnrestrictions.editor;
+
+import javax.swing.JComboBox;
+/**
+ * A combo box for selecting a turn restriction type.
+ */
+public class TurnRestrictionComboBox extends JComboBox{
+	
+	/**
+	 * Constructor 
+	 * 
+	 * @param model the combo box model. Must not be null.
+	 */
+	public TurnRestrictionComboBox(TurnRestrictionComboBoxModel model){
+		super(model);
+		setEditable(false);
+		setRenderer(new TurnRestrictionTypeRenderer());
+	}
+	
+	/**
+	 * Replies the turn restriction combo box model 
+	 * 
+	 * @return the turn restriction combo box model
+	 */
+	public TurnRestrictionComboBoxModel getTurnRestrictionComboBoxModel() {
+		return (TurnRestrictionComboBoxModel)getModel();
+	}
+}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionComboBoxModel.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionComboBoxModel.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionComboBoxModel.java	(revision 20489)
@@ -0,0 +1,121 @@
+package org.openstreetmap.josm.plugins.turnrestrictions.editor;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Observable;
+import java.util.Observer;
+import java.util.logging.Logger;
+
+import javax.swing.ComboBoxModel;
+import javax.swing.event.EventListenerList;
+import javax.swing.event.ListDataEvent;
+import javax.swing.event.ListDataListener;
+
+import org.openstreetmap.josm.tools.CheckParameterUtil;
+
+/**
+ * This is a model for a combo box to select a turn restriction type. The
+ * user can choose from a list of standard types but the model also supports
+ * non-standard tag values in the OSM data. 
+ *
+ */
+public class TurnRestrictionComboBoxModel implements ComboBoxModel, Observer{
+	static private final Logger logger = Logger.getLogger(TurnRestrictionComboBoxModel.class.getName());
+	
+	private TurnRestrictionEditorModel model;
+	final private List<Object> values = new ArrayList<Object>();
+	private String selectedTagValue = null;
+	private final transient EventListenerList listeners = new EventListenerList();
+	
+	/**
+	 * Populates the model with the list of standard values. If the
+	 * data contains a non-standard value it is displayed in the combo
+	 * box as an additional element. 
+	 */
+	protected void populate() {
+		values.clear();
+		for (TurnRestrictionType type: TurnRestrictionType.values()) {
+			values.add(type);
+		}		
+		
+		String tagValue = model.getRestrictionTagValue();
+		if (tagValue == null) {
+			selectedTagValue = null;
+		} else {
+			TurnRestrictionType type = TurnRestrictionType.fromTagValue(tagValue);
+			if (type == null) {
+				values.add(0, tagValue);
+				selectedTagValue = tagValue;
+			} else {
+				selectedTagValue = type.getTagValue();
+			}
+		}
+		fireContentsChanged();
+	}
+	
+	/**
+	 * Creates the combo box model. 
+	 * 
+	 * @param model the turn restriction editor model. Must not be null.
+	 */
+	public TurnRestrictionComboBoxModel(TurnRestrictionEditorModel model){
+		CheckParameterUtil.ensureParameterNotNull(model, "model");
+		this.model = model;
+		model.addObserver(this);
+		populate();
+	}
+
+	public Object getSelectedItem() {
+		TurnRestrictionType type = TurnRestrictionType.fromTagValue(selectedTagValue);
+		if (type != null) return type;
+		return selectedTagValue;
+	}
+
+	public void setSelectedItem(Object anItem) {
+		String tagValue = null;
+		if (anItem instanceof String) {
+			tagValue = (String)anItem;
+		} else if (anItem instanceof TurnRestrictionType){
+			tagValue = ((TurnRestrictionType)anItem).getTagValue();
+		}
+		model.setRestrictionTagValue(tagValue);
+	}
+
+	public Object getElementAt(int index) {
+		return values.get(index);
+	}
+
+	public int getSize() {
+		return values.size();
+	}
+	
+	public void addListDataListener(ListDataListener l) {
+		listeners.add(ListDataListener.class, l);		
+	}
+	
+	public void removeListDataListener(ListDataListener l) {
+		listeners.remove(ListDataListener.class, l);		
+	}
+	
+	protected void fireContentsChanged() {
+		for(ListDataListener l: listeners.getListeners(ListDataListener.class)) {
+			l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, 0, getSize()));
+		}
+	}
+	
+	/* ------------------------------------------------------------------------------------ */
+	/* interface Observer                                                                   */
+	/* ------------------------------------------------------------------------------------ */
+	public void update(Observable o, Object arg) {		
+		String tagValue = model.getRestrictionTagValue();
+		if (tagValue == null && selectedTagValue != null) {
+			populate();
+		} else if (tagValue != null && selectedTagValue == null){
+			populate();
+		} else if (tagValue != null) {
+			if (!tagValue.equals(selectedTagValue)) {
+				populate();
+			}
+		} 
+	}
+}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionEditor.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionEditor.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionEditor.java	(revision 20489)
@@ -0,0 +1,643 @@
+package org.openstreetmap.josm.plugins.turnrestrictions.editor;
+
+import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
+import static org.openstreetmap.josm.tools.I18n.tr;
+import static org.openstreetmap.josm.tools.I18n.trn;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.logging.Logger;
+
+import javax.swing.AbstractAction;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JSplitPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JToolBar;
+import javax.swing.KeyStroke;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.AddCommand;
+import org.openstreetmap.josm.command.ChangeCommand;
+import org.openstreetmap.josm.command.ConflictAddCommand;
+import org.openstreetmap.josm.data.conflict.Conflict;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.gui.DefaultNameFormatter;
+import org.openstreetmap.josm.gui.HelpAwareOptionPane;
+import org.openstreetmap.josm.gui.SideButton;
+import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec;
+import org.openstreetmap.josm.gui.dialogs.relation.RelationEditor;
+import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.ImageProvider;
+
+public class TurnRestrictionEditor extends JDialog {
+	final private static Logger logger = Logger.getLogger(TurnRestrictionEditor.class.getName());
+	
+    /** the property name for the current turn restriction
+     * @see #setRelation(Relation)
+     * @see #getRelation()
+     */
+    static public final String TURN_RESTRICION_PROP = RelationEditor.class.getName() + ".turnRestriction";
+
+    /** the property name for the current relation snapshot
+     * @see #getRelationSnapshot()
+     */
+    static public final String TURN_RESTRICION_SNAPSHOT_PROP = RelationEditor.class.getName() + ".turnRestrictionSnapshot";
+    
+    /**
+     * The turn restriction this editor is working on
+     */
+    protected Relation turnRestriction;
+
+    /**
+     * The version of the turn restriction when editing is started.  This is
+     * null if a new turn restriction is created. 
+     */
+    protected Relation turnRestrictionSnapshot;
+
+    /** the data layer the turn restriction belongs to */
+    private OsmDataLayer layer;
+	
+    private JosmSelectionPanel pnlJosmSelection;
+    private BasicEditorPanel pnlBasicEditor;
+    private TurnRestrictionEditorModel editorModel;
+    
+    /**
+     * builds the panel with the OK and the Cancel button
+     *
+     * @return the panel with the OK and the Cancel button
+     */
+    protected JPanel buildOkCancelButtonPanel() {
+        JPanel pnl = new JPanel();
+        pnl.setLayout(new FlowLayout(FlowLayout.CENTER));
+
+        pnl.add(new SideButton(new OKAction()));
+        pnl.add(new SideButton(new CancelAction()));
+        
+        // FIXME: fix help topics
+        pnl.add(new SideButton(new ContextSensitiveHelpAction(ht("/Plugin/turnrestrictions"))));
+        return pnl;
+    }
+    
+    /**
+     * builds the panel which displays the JOSM selection 
+     * @return
+     */
+    protected JPanel buildJOSMSelectionPanel() {
+    	pnlJosmSelection = new JosmSelectionPanel(layer.data);
+    	return pnlJosmSelection;
+    }
+    
+    /**
+     * Builds the panel with the editor masks (the left panel in the split pane of 
+     * this dialog)
+     * 
+     * @return
+     */
+    protected JPanel buildEditorPanel() {
+    	JPanel pnl = new JPanel(new BorderLayout());
+    	JTabbedPane tpEditors = new JTabbedPane();
+    	tpEditors.add(pnlBasicEditor =new BasicEditorPanel(editorModel));
+    	tpEditors.setTitleAt(0, tr("Basic"));
+    	tpEditors.setToolTipTextAt(0, tr("Edit basic attributes of a turn restriction"));
+    	pnl.add(tpEditors, BorderLayout.CENTER);
+    	return pnl;
+    }
+    
+    /**
+     * Builds the content panel, i.e. the core area of the dialog with the editor
+     * masks and the JOSM selection view 
+     * 
+     * @return
+     */
+    protected JPanel buildContentPanel() {
+    	JPanel pnl = new JPanel(new BorderLayout());
+    	final JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
+    	pnl.add(sp, BorderLayout.CENTER);
+    	sp.setLeftComponent(buildEditorPanel());
+    	sp.setRightComponent(buildJOSMSelectionPanel());
+        addWindowListener(new WindowAdapter() {
+            @Override
+            public void windowOpened(WindowEvent e) {
+                // has to be called when the window is visible, otherwise
+                // no effect
+                sp.setDividerLocation(0.7);
+            }
+        });
+
+    	return pnl;
+    }
+    
+    /**
+     * Creates the toolbar
+     *
+     * @return the toolbar
+     */
+    protected JToolBar buildToolBar() {
+        JToolBar tb  = new JToolBar();
+        tb.setFloatable(false);
+        tb.add(new ApplyAction());
+        return tb;
+    }
+    
+    /**
+     * builds the UI
+     */
+    protected void build() {    	
+    	editorModel = new TurnRestrictionEditorModel();
+    	Container c = getContentPane();
+    	c.setLayout(new BorderLayout());
+    	c.add(buildToolBar(), BorderLayout.NORTH);
+    	c.add(buildContentPanel(), BorderLayout.CENTER);    	
+    	c.add(buildOkCancelButtonPanel(), BorderLayout.SOUTH);
+    	setSize(600,600);
+    }    
+	
+	/**
+    * Creates a new turn restriction editor
+    *
+    * @param owner the component relative to which the dialog is displayed 
+    * @param layer  the {@see OsmDataLayer} in whose context a relation is edited. Must not be null.
+    * @throws IllegalArgumentException thrown if layer is null
+    */
+	public TurnRestrictionEditor(Component owner, OsmDataLayer layer) {
+		this(owner, layer, null);
+	}
+	
+	 /**
+     * Creates a new turn restriction editor
+     *
+     * @param owner the component relative to which the dialog is displayed 
+     * @param layer  the {@see OsmDataLayer} in whose context a relation is edited. Must not be null.
+     * @param turnRestriction the relation. Can be null if a new relation is to be edited.
+     * @throws IllegalArgumentException thrown if layer is null
+     */
+    public TurnRestrictionEditor(Component owner, OsmDataLayer layer, Relation turnRestriction)  throws IllegalArgumentException{
+    	super(JOptionPane.getFrameForComponent(owner),false /* not modal */);
+        CheckParameterUtil.ensureParameterNotNull(layer, "layer");
+        this.layer = layer;
+        build();
+        setTurnRestriction(turnRestriction);
+    }
+    
+    /**
+     * Replies the currently edited turn restriction
+     *
+     * @return the currently edited relation
+     */
+    protected Relation getTurnRestriction() {
+        return turnRestriction;
+    }
+
+    /**
+     * Sets the currently edited turn restriction. Creates a snapshot of the current
+     * state of the turn restriction. See {@see #getTurnRestrictionSnapshot()}
+     *
+     * {@code turnRestriction} can be null if a new restriction is created. A turn
+     * restriction which isn't assigned to a data set is allowed too. If {@code turnRestriction}
+     * is already assigned to a dataset, the dataset of {@see #getLayer()} is required, otherwise
+     * a {@see IllegalArgumentException} is thrown.
+     * 
+     * @param turnRestriction the turn restriction
+     * @throws IllegalArgumentException thrown if {@code turnRestriction} belongs to a different dataset than
+     * that owned by the layer {@see #getLayer()}
+     */
+    protected void setTurnRestriction(Relation turnRestriction) {
+      
+        if (turnRestriction == null) {
+        	editorModel.populate(new Relation(), getLayer().data);
+        } else if (turnRestriction.getDataSet() == null) {
+        	editorModel.populate(turnRestriction, getLayer().data);
+        } else if (turnRestriction.getDataSet() == getLayer().data) {
+        	editorModel.populate(turnRestriction);
+        } else {
+        	throw new IllegalArgumentException(MessageFormat.format("turnRestriction must not belong to the layer {0}", getLayer().getName()));
+        }
+        setTurnRestrictionSnapshot(turnRestriction == null ? null : new Relation(turnRestriction));
+        Relation oldValue = this.turnRestriction;
+        this.turnRestriction = turnRestriction;
+        if (this.turnRestriction != oldValue) {
+            support.firePropertyChange(TURN_RESTRICION_PROP, oldValue, this.turnRestriction);
+        }
+        updateTitle();
+    }
+    
+    /**
+     * updates the title of the turn restriction editor
+     */
+    protected void updateTitle() {
+        if (getTurnRestriction() == null) {
+            setTitle(tr("Create new turn restriction in layer ''{0}''", layer.getName()));
+        } else if (getTurnRestriction().isNew()) {
+            setTitle(tr("Edit new turn restriction in layer ''{0}''", layer.getName()));
+        } else {
+            setTitle(tr("Edit turn restriction #{0} in layer ''{1}''", Long.toString(turnRestriction.getId()), layer.getName()));
+        }
+    }
+    
+    /**
+     * Replies the {@see OsmDataLayer} in whose context this relation editor is
+     * open
+     *
+     * @return the {@see OsmDataLayer} in whose context this relation editor is
+     * open
+     */
+    protected OsmDataLayer getLayer() {
+        return layer;
+    }
+
+    /**
+     * Replies the state of the edited relation when the editor has been launched
+     *
+     * @return the state of the edited relation when the editor has been launched
+     */
+    protected Relation getTurnRestrictionSnapshot() {
+        return turnRestrictionSnapshot;
+    }
+
+    /**
+     * Sets the turn restriction snapshot
+     * 
+     * @param snapshot the snapshot
+     */
+    protected void setTurnRestrictionSnapshot(Relation snapshot) {
+        Relation oldValue = turnRestrictionSnapshot;
+        turnRestrictionSnapshot = snapshot;
+        if (turnRestrictionSnapshot != oldValue) {
+            support.firePropertyChange(TURN_RESTRICION_SNAPSHOT_PROP, oldValue, turnRestrictionSnapshot);
+        }
+    }
+    
+    /**
+     * Replies true if the currently edited turn restriction has been changed elsewhere.
+     *
+     * In this case a turn restriction editor can't apply updates to the turn restriction
+     * directly. Rather, it has to create a conflict.
+     *
+     * @return true if the currently edited turn restriction has been changed elsewhere.
+     */
+    protected boolean isDirtyTurnRestriction() {
+        return ! turnRestriction.hasEqualSemanticAttributes(turnRestrictionSnapshot);
+    }
+    
+    /**
+     * Replies the editor model for this editor 
+     */
+    public TurnRestrictionEditorModel getModel() {
+    	return editorModel;
+    }
+    
+    public void setVisible(boolean visible) {
+    	if (visible && ! isVisible()) {
+    		pnlJosmSelection.wireListeners();
+    		editorModel.registerAsEventListener();
+    	} else if (!visible && isVisible()) {
+    		pnlJosmSelection.unwireListeners();
+    		editorModel.unregisterAsEventListener();
+    	}
+    	super.setVisible(visible);
+    	if (!visible){
+    		dispose();
+    	}
+    }
+    
+    /* ----------------------------------------------------------------------- */
+    /* property change support                                                 */
+    /* ----------------------------------------------------------------------- */
+    final private PropertyChangeSupport support = new PropertyChangeSupport(this);
+
+    @Override
+    public void addPropertyChangeListener(PropertyChangeListener listener) {
+        this.support.addPropertyChangeListener(listener);
+    }
+
+    @Override
+    public void removePropertyChangeListener(PropertyChangeListener listener) {
+        this.support.removePropertyChangeListener(listener);
+    }
+    
+    /**
+     * The abstract base action for applying the updates of a turn restriction
+     * to the dataset.
+     */
+    abstract class SavingAction extends AbstractAction {
+    	
+    	/**
+    	 * Replies the list of relation members in {@code r} which refer to
+    	 * a deleted or invisible primitives.
+    	 * 
+    	 * @param r the relation 
+    	 * @return the list of relation members in {@code r} which refer to
+    	 * a deleted or invisible member
+    	 */
+    	protected List<RelationMember> getDeletedRelationMembers(Relation r) {
+    		List<RelationMember> ret = new ArrayList<RelationMember>();
+    		for(RelationMember rm: r.getMembers()) {
+    			if (rm.getMember().isDeleted() || !rm.getMember().isVisible()) {
+    				ret.add(rm);
+    			}
+    		}
+    		return ret;
+    	}
+    	
+    	/**
+    	 * Removes all members referring to deleted or invisible primitives
+    	 * from the turn restriction {@code tr}.
+    	 * 
+    	 * @param tr  the turn restriction
+    	 */
+    	protected void removeDeletedMembers(Relation tr) {
+    		List<RelationMember> members = tr.getMembers();
+    		for(Iterator<RelationMember> it = members.iterator(); it.hasNext();) {
+    			RelationMember rm = it.next();
+    			if (rm.getMember().isDeleted() || !rm.getMember().isVisible()) {
+    				it.remove();
+    			}
+    		}
+    		tr.setMembers(members);
+    	}
+    	
+    	/**
+    	 * Asks the user how to proceed if a turn restriction refers to deleted or invisible
+    	 * primitives.
+    	 * 
+    	 * If this method returns true the respective members should be removed and the turn
+    	 * restriction should be saved anyway. If it replies false, the turn restriction must not
+    	 * be saved.  
+    	 * 
+    	 * @param deletedMembers the list of members referring to deleted or invisible primitives  
+    	 * @return the confirmation 
+    	 */
+    	protected boolean confirmSaveTurnRestrictionWithDeletePrimitives(List<RelationMember> deletedMembers) {    		    		
+    		StringBuffer sb = new StringBuffer();
+    		sb.append("<html>");
+    		sb.append(trn("This turn restriction refers to an object which was deleted outside "
+    		           + "of this turn restriction editor:",
+    		           "This turn restriction refers to {0} which were deleted outside "
+    		           + "of this turn restriction editor:", deletedMembers.size(), deletedMembers.size()));
+    		sb.append("<ul>");
+    		for(RelationMember rm: deletedMembers){
+    			sb.append("<li>");
+    			if (!rm.getRole().equals("")) {
+    				sb.append(rm.getRole()).append(": ");
+    			}
+    			sb.append(rm.getMember().getDisplayName(DefaultNameFormatter.getInstance()));
+    			sb.append("</li>");
+    		}
+    		sb.append(tr("Updates to this turn restriction can''t be saved unless deleted members are removed.<br>"
+    				+ "How to you want to proceed?"));
+    		
+    		ButtonSpec[] options = new ButtonSpec[] {
+    				new ButtonSpec(
+    					tr("Remove deleted members and save"),
+    					ImageProvider.get("OK"),
+    					tr("Remove deleted members and save"),
+    					null
+    			     ),
+     				  new ButtonSpec(
+        					tr("Cancel and return to editor"),
+        					ImageProvider.get("cancel"),
+        					tr("Cancel and return to editor"),
+        					null
+        			   )
+    		};
+    		
+    		int ret = HelpAwareOptionPane.showOptionDialog(
+    				TurnRestrictionEditor.this,
+    				sb.toString(),
+    				tr("Deleted members in turn restriction"),
+    				JOptionPane.WARNING_MESSAGE,
+    				null, // no special icon
+    				options,
+    				options[1], // cancel is default
+    				null // FIXME: provide help topic
+    		);    		
+    		return ret == 0 /* OK button */; 
+    	}
+    	
+        /**
+         * apply updates to a new turn restriction
+         */
+        protected boolean applyNewTurnRestriction() {        	
+            Relation newTurnRestriction = new Relation();
+            editorModel.apply(newTurnRestriction);
+
+            // If the user wanted to create a new turn restriction, but didn't add any members or
+            // tags, don't add an empty relation
+            if (newTurnRestriction.getMembersCount() == 0 && !newTurnRestriction.hasKeys())
+                return true;
+            
+            // check whether the turn restriction refers to new 
+            List<RelationMember> deletedMembers = getDeletedRelationMembers(newTurnRestriction);
+            if (!deletedMembers.isEmpty()) {
+            	if (!confirmSaveTurnRestrictionWithDeletePrimitives(deletedMembers)) {
+            		return false;
+            	}
+            	removeDeletedMembers(newTurnRestriction);
+            }
+            
+            Main.main.undoRedo.add(new AddCommand(getLayer(),newTurnRestriction));
+
+            // make sure everybody is notified about the changes
+            //
+            TurnRestrictionEditor.this.setTurnRestriction(newTurnRestriction);
+            TurnRestrictionEditorManager.getInstance().updateContext(
+                    getLayer(),
+                    getTurnRestriction(),
+                    TurnRestrictionEditor.this
+            );
+            return true;
+        }
+
+        /**
+         * Apply the updates for an existing turn restriction which has been changed
+         * outside of the turn restriction editor.
+         *
+         */
+        protected void applyExistingConflictingTurnRestriction() {
+            Relation toUpdate = new Relation(getTurnRestriction());
+            editorModel.apply(toUpdate);
+            Conflict<Relation> conflict = new Conflict<Relation>(getTurnRestriction(), toUpdate);
+            Main.main.undoRedo.add(new ConflictAddCommand(getLayer(),conflict));
+        }
+
+        /**
+         * Apply the updates for an existing turn restriction which has not been changed
+         * outside of the turn restriction editor.
+         */
+        protected void applyExistingNonConflictingTurnRestriction() {
+        	Relation toUpdate = new Relation(getTurnRestriction());
+            editorModel.apply(toUpdate);
+            Main.main.undoRedo.add(new ChangeCommand(getTurnRestriction(), toUpdate));
+            // this will refresh the snapshot and update the dialog title
+            //
+            setTurnRestriction(getTurnRestriction());
+        }
+
+        protected boolean confirmClosingBecauseOfDirtyState() {
+            ButtonSpec [] options = new ButtonSpec[] {
+                    new ButtonSpec(
+                            tr("Yes, create a conflict and close"),
+                            ImageProvider.get("ok"),
+                            tr("Create a conflict and close this turn restriction editor") ,
+                            null /* no specific help topic */
+                    ),
+                    new ButtonSpec(
+                            tr("No, continue editing"),
+                            ImageProvider.get("cancel"),
+                            tr("Return to the turn restriction editor and resume editing") ,
+                            null /* no specific help topic */
+                    )
+            };
+
+            int ret = HelpAwareOptionPane.showOptionDialog(
+                    Main.parent,
+                    tr("<html>This turn restriction has been changed outside of the editor.<br>"
+                            + "You cannot apply your changes and continue editing.<br>"
+                            + "<br>"
+                            + "Do you want to create a conflict and close the editor?</html>"),
+                            tr("Conflict in data"),
+                            JOptionPane.WARNING_MESSAGE,
+                            null,
+                            options,
+                            options[0], // OK is default
+                            null // FIXME: provide help topic
+            );
+            return ret == 0;
+        }
+
+        protected void warnDoubleConflict() {
+            JOptionPane.showMessageDialog(
+                    Main.parent,
+                    tr("<html>Layer ''{0}'' already has a conflict for object<br>"
+                            + "''{1}''.<br>"
+                            + "Please resolve this conflict first, then try again.</html>",
+                            getLayer().getName(),
+                            getTurnRestriction().getDisplayName(DefaultNameFormatter.getInstance())
+                    ),
+                    tr("Already participating in a conflict"),
+                    JOptionPane.WARNING_MESSAGE
+            );
+        }
+    }
+
+    class ApplyAction extends SavingAction {
+        public ApplyAction() {
+            putValue(SHORT_DESCRIPTION, tr("Apply the current updates"));
+            putValue(SMALL_ICON, ImageProvider.get("save"));
+            putValue(NAME, tr("Apply"));
+            setEnabled(true);
+        }
+
+        public void run() {
+            if (getTurnRestriction() == null) {
+                applyNewTurnRestriction();
+                return;
+            } 
+            
+            Relation toUpdate = new Relation(getTurnRestriction());
+            editorModel.apply(toUpdate);
+            if (TurnRestrictionEditorModel.hasSameMembersAndTags(toUpdate, getTurnRestriction()))
+            	// nothing to update 
+            	return;
+            
+            if (isDirtyTurnRestriction()) {
+                if (confirmClosingBecauseOfDirtyState()) {
+                    if (getLayer().getConflicts().hasConflictForMy(getTurnRestriction())) {
+                        warnDoubleConflict();
+                        return;
+                    }
+                    applyExistingConflictingTurnRestriction();
+                    setVisible(false);
+                }
+            } else {
+                applyExistingNonConflictingTurnRestriction();
+            }            
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            run();
+        }
+    }
+    
+    class OKAction extends SavingAction {
+        public OKAction() {
+            putValue(SHORT_DESCRIPTION, tr("Apply the updates and close the dialog"));
+            putValue(SMALL_ICON, ImageProvider.get("ok"));
+            putValue(NAME, tr("OK"));
+            setEnabled(true);
+        }
+
+        public void run() {
+            if (getTurnRestriction() == null) {
+            	// it's a new turn restriction. Try to save it and close the dialog
+                if (applyNewTurnRestriction()) {
+                	setVisible(false);
+                }
+                return;
+            } 
+            
+            Relation toUpdate = new Relation(getTurnRestriction());
+            editorModel.apply(toUpdate);
+            if (TurnRestrictionEditorModel.hasSameMembersAndTags(toUpdate, getTurnRestriction())){
+            	// nothing to update 
+            	setVisible(false);
+            	return;
+            }
+            
+            if (isDirtyTurnRestriction()) {
+            	// the turn restriction this editor is working on has changed outside
+            	// of the editor. 
+                if (confirmClosingBecauseOfDirtyState()) {
+                    if (getLayer().getConflicts().hasConflictForMy(getTurnRestriction())) {
+                        warnDoubleConflict();
+                        return;
+                    }
+                    applyExistingConflictingTurnRestriction();
+                } else
+                    return;
+            } else {
+                applyExistingNonConflictingTurnRestriction();
+            }        
+            setVisible(false);
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            run();
+        }
+    }
+
+    /**
+     * Action for canceling the current dialog 
+     */
+    class CancelAction extends AbstractAction {
+        public CancelAction() {
+            putValue(SHORT_DESCRIPTION, tr("Cancel the updates and close the dialog"));
+            putValue(SMALL_ICON, ImageProvider.get("cancel"));
+            putValue(NAME, tr("Cancel"));
+            putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke("ESCAPE"));
+            TurnRestrictionEditor.this.getRootPane().registerKeyboardAction(this,KeyStroke.getKeyStroke("ESCAPE"), JComponent.WHEN_IN_FOCUSED_WINDOW);
+            setEnabled(true);
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            setVisible(false);
+        }
+    }
+}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionEditorManager.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionEditorManager.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionEditorManager.java	(revision 20489)
@@ -0,0 +1,298 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.turnrestrictions.editor;
+
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.Toolkit;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map.Entry;
+import java.util.logging.Logger;
+
+import org.openstreetmap.josm.data.osm.PrimitiveId;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+
+/**
+ * TurnRestrictionEditorManager keeps track of the open turn restriction editors.
+ *
+ */
+public class TurnRestrictionEditorManager extends WindowAdapter implements MapView.LayerChangeListener{
+	static private final Logger logger = Logger.getLogger(TurnRestrictionEditorManager.class.getName());
+
+    /** keeps track of open relation editors */
+    static TurnRestrictionEditorManager instance;
+
+    /**
+     * Replies the singleton {@see TurnRestrictionEditorManager}
+     *
+     * @return the singleton {@see TurnRestrictionEditorManager}
+     */
+    static public TurnRestrictionEditorManager getInstance() {
+        if (TurnRestrictionEditorManager.instance == null) {
+            TurnRestrictionEditorManager.instance = new TurnRestrictionEditorManager();
+            MapView.addLayerChangeListener(TurnRestrictionEditorManager.instance);
+        }
+        return TurnRestrictionEditorManager.instance;
+    }
+
+    /**
+     * Helper class for keeping the context of a turn restriction editor. A turn
+     * restriction editor is open for turn restriction in a  {@see OsmDataLayer}
+     */
+    static private class DialogContext {
+        public final PrimitiveId primitiveId;
+        public final OsmDataLayer layer;
+
+        public DialogContext(OsmDataLayer layer, PrimitiveId id) {
+            this.layer = layer;
+            this.primitiveId = id;
+        }
+
+        @Override
+		public int hashCode() {
+			final int prime = 31;
+			int result = 1;
+			result = prime * result + ((layer == null) ? 0 : layer.hashCode());
+			result = prime * result
+					+ ((primitiveId == null) ? 0 : primitiveId.hashCode());
+			return result;
+		}
+
+		@Override
+		public boolean equals(Object obj) {
+			if (this == obj)
+				return true;
+			if (obj == null)
+				return false;
+			if (getClass() != obj.getClass())
+				return false;
+			DialogContext other = (DialogContext) obj;
+			if (layer == null) {
+				if (other.layer != null)
+					return false;
+			} else if (!layer.equals(other.layer))
+				return false;
+			if (primitiveId == null) {
+				if (other.primitiveId != null)
+					return false;
+			} else if (!primitiveId.equals(other.primitiveId))
+				return false;
+			return true;
+		}
+
+		public boolean matchesLayer(OsmDataLayer layer) {
+            if (layer == null) return false;
+            return this.layer.equals(layer);
+        }
+
+        @Override
+        public String toString() {
+            return "[Context: layer=" + layer.getName() + ",relation=" + primitiveId + "]";
+        }
+    }
+
+    /** the map of open dialogs */
+    private final HashMap<DialogContext, TurnRestrictionEditor> openDialogs =  new HashMap<DialogContext, TurnRestrictionEditor>();
+
+    /**
+     * constructor
+     */
+    public TurnRestrictionEditorManager(){}
+    
+    /**
+     * Register the editor for a turn restriction managed by a
+     * {@see OsmDataLayer}.
+     *
+     * @param layer the layer
+     * @param relation the turn restriction
+     * @param editor the editor
+     */
+    public void register(OsmDataLayer layer, Relation relation, TurnRestrictionEditor editor) {
+        if (relation == null) {
+            relation = new Relation();
+        }
+        DialogContext context = new DialogContext(layer, relation.getPrimitiveId());
+        openDialogs.put(context, editor);
+        editor.addWindowListener(this);
+    }
+
+    public void updateContext(OsmDataLayer layer, Relation relation, TurnRestrictionEditor editor) {
+        // lookup the entry for editor and remove it
+        //
+        for (DialogContext context: openDialogs.keySet()) {
+            if (openDialogs.get(context) == editor) {
+                openDialogs.remove(context);
+                break;
+            }
+        }
+        // don't add a window listener. Editor is already known to the relation dialog manager
+        //
+        DialogContext context = new DialogContext(layer, relation.getPrimitiveId());
+        openDialogs.put(context, editor);
+    }
+
+    /**
+     * Closes the editor open for a specific layer and a specific relation.
+     *
+     * @param layer  the layer
+     * @param relation the relation
+     */
+    public void close(OsmDataLayer layer, Relation relation) {
+        DialogContext context = new DialogContext(layer, relation);
+        TurnRestrictionEditor editor = openDialogs.get(context);
+        if (editor != null) {
+            editor.setVisible(false);
+        }
+    }
+
+    /**
+     * Replies true if there is an open turn restriction editor for the turn
+     * restriction managed
+     * by the given layer. Replies false if relation is null.
+     *
+     * @param layer  the layer
+     * @param relation  the turn restriction. May be null.
+     * @return true if there is an open turn restriction editor for the turn restriction managed
+     * by the given layer; false otherwise
+     */
+    public boolean isOpenInEditor(OsmDataLayer layer, Relation relation) {
+        if (relation == null) return false;
+        DialogContext context = new DialogContext(layer, relation.getPrimitiveId());
+        return openDialogs.keySet().contains(context);
+
+    }
+
+    /**
+     * Replies the editor for the turn restriction managed by layer. Null, if no such editor
+     * is currently open. Returns null, if relation is null.
+     *
+     * @param layer the layer
+     * @param relation the relation
+     * @return the editor for the turn restriction managed by layer. Null, if no such editor
+     * is currently open.
+     *
+     * @see #isOpenInEditor(OsmDataLayer, Relation)
+     */
+    public TurnRestrictionEditor getEditorForRelation(OsmDataLayer layer, Relation relation) {
+        if (relation == null) return null;
+        DialogContext context = new DialogContext(layer, relation.getPrimitiveId());
+        return openDialogs.get(context);
+    }
+
+    @Override
+    public void windowClosed(WindowEvent e) {
+    	TurnRestrictionEditor editor = (TurnRestrictionEditor)e.getWindow();
+        DialogContext context = null;
+        for (DialogContext c : openDialogs.keySet()) {
+            if (editor.equals(openDialogs.get(c))) {
+                context = c;
+                break;
+            }
+        }
+        if (context != null) {
+            openDialogs.remove(context);
+        }
+    }
+
+	/**
+     * Positions an {@see TurnRestrictionEditor} centered on the screen
+     *
+     * @param editor the editor
+     */
+    protected void centerOnScreen(TurnRestrictionEditor editor) {
+        Point p = new Point(0,0);
+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
+        p.x = (d.width - editor.getSize().width)/2;
+        p.y = (d.height - editor.getSize().height)/2;
+        p.x = Math.max(p.x,0);
+        p.y = Math.max(p.y,0);
+        editor.setLocation(p);
+    }
+
+    /**
+     * Replies true, if there is another open {@see TurnRestrictionEditor} whose
+     * upper left corner is close to <code>p</code>.
+     *
+     * @param p  the reference point to check
+     * @return true, if there is another open {@see TurnRestrictionEditor} whose
+     * upper left corner is close to <code>p</code>.
+     */
+    protected boolean hasEditorWithCloseUpperLeftCorner(Point p) {
+        for (TurnRestrictionEditor editor: openDialogs.values()) {
+            Point corner = editor.getLocation();
+            if (p.x >= corner.x -5 && corner.x + 5 >= p.x
+                    && p.y >= corner.y -5 && corner.y + 5 >= p.y)
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * Positions a {@see TurnRestrictionEditor} close to the center of the screen, in such
+     * a way, that it doesn't entirely cover another {@see TurnRestrictionEditor}
+     *
+     * @param editor
+     */
+    protected void positionCloseToScreenCenter(TurnRestrictionEditor editor) {
+        Point p = new Point(0,0);
+        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
+        p.x = (d.width - editor.getSize().width)/2;
+        p.y = (d.height - editor.getSize().height)/2;
+        p.x = Math.max(p.x,0);
+        p.y = Math.max(p.y,0);
+        while(hasEditorWithCloseUpperLeftCorner(p)) {
+            p.x += 20;
+            p.y += 20;
+        }
+        editor.setLocation(p);
+    }
+
+    /**
+     * Positions a {@see TurnRestrictionEditor} on the screen. Tries to center it on the
+     * screen. If it hides another instance of an editor at the same position this
+     * method tries to reposition <code>editor</code> by moving it slightly down and
+     * slightly to the right.
+     *
+     * @param editor the editor
+     */
+    public void positionOnScreen(TurnRestrictionEditor editor) {
+        if (editor == null) return;
+        if (openDialogs.isEmpty()) {
+            centerOnScreen(editor);
+        } else {
+            positionCloseToScreenCenter(editor);
+        }
+    }
+    
+    /* ----------------------------------------------------------------------------------- */
+    /* interface MapView.LayerChangeListener                                               */
+    /* ----------------------------------------------------------------------------------- */
+    /**
+     * called when a layer is removed
+     *
+     */
+    public void layerRemoved(Layer oldLayer) {
+        if (oldLayer == null || ! (oldLayer instanceof OsmDataLayer))
+            return;
+        OsmDataLayer dataLayer = (OsmDataLayer)oldLayer;
+
+        Iterator<Entry<DialogContext,TurnRestrictionEditor>> it = openDialogs.entrySet().iterator();
+        while(it.hasNext()) {
+            Entry<DialogContext,TurnRestrictionEditor> entry = it.next();
+            if (entry.getKey().matchesLayer(dataLayer)) {
+            	TurnRestrictionEditor editor = entry.getValue();
+                it.remove();
+                editor.setVisible(false);
+                editor.dispose();
+            }
+        }
+    }
+
+    public void activeLayerChange(Layer oldLayer, Layer newLayer) {/* irrelevant in this context */}
+    public void layerAdded(Layer newLayer) {/* irrelevant in this context */}
+}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionEditorModel.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionEditorModel.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionEditorModel.java	(revision 20489)
@@ -0,0 +1,441 @@
+package org.openstreetmap.josm.plugins.turnrestrictions.editor;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Observable;
+import java.util.logging.Logger;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
+import org.openstreetmap.josm.data.osm.PrimitiveId;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.data.osm.TagCollection;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
+import org.openstreetmap.josm.data.osm.event.DataChangedEvent;
+import org.openstreetmap.josm.data.osm.event.DataSetListener;
+import org.openstreetmap.josm.data.osm.event.DatasetEventManager;
+import org.openstreetmap.josm.data.osm.event.NodeMovedEvent;
+import org.openstreetmap.josm.data.osm.event.PrimitivesAddedEvent;
+import org.openstreetmap.josm.data.osm.event.PrimitivesRemovedEvent;
+import org.openstreetmap.josm.data.osm.event.RelationMembersChangedEvent;
+import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
+import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
+import org.openstreetmap.josm.data.osm.event.DatasetEventManager.FireMode;
+import org.openstreetmap.josm.tools.CheckParameterUtil;
+
+/**
+ * This is the model for the turn restriction editor. It keeps the editing state
+ * for a single turn restriction. 
+ * 
+ */
+public class TurnRestrictionEditorModel extends Observable implements DataSetListener{
+	static private final Logger logger = Logger.getLogger(TurnRestrictionEditorModel.class.getName());
+	
+	/**
+	 * Replies true if {@code tp1} and {@code tp2} have the same tags and
+	 * the same members 
+	 * 
+	 * @param tp1 a turn restriction. Must not be null. 
+	 * @param tp2 a turn restriction . Must not be null.
+	 * @return true if {@code tp1} and {@code tp2} have the same tags and
+	 * the same members
+	 * @throws IllegalArgumentException thrown if {@code tp1} is null
+	 * @throws IllegalArgumentException thrown if {@code tp2} is null
+	 */
+	static public boolean hasSameMembersAndTags(Relation tp1, Relation tp2) throws IllegalArgumentException {
+		CheckParameterUtil.ensureParameterNotNull(tp1, "tp1");
+		CheckParameterUtil.ensureParameterNotNull(tp2, "tp2");
+		if (!TagCollection.from(tp1).asSet().equals(TagCollection.from(tp2).asSet())) return false;
+		if (tp1.getMembersCount() != tp2.getMembersCount()) return false;
+		for(int i=0; i < tp1.getMembersCount();i++){
+			if (!tp1.getMember(i).equals(tp2.getMember(i))) return false;
+		}
+		return true;
+	}
+	
+	
+	/** 
+	 * holds the relation member of turn restriction relation from which the turn
+	 * restriction leg with role 'from' was initialized. This is needed if OSM
+	 * data contains turn restrictions with multiple 'from' members. The
+	 * field is null if a turn restriction didn't have a member with role
+	 * 'from'.
+	 */
+	private RelationMember fromRelationMember;
+	
+	/** 
+	 * holds the relation member of turn restriction relation from which the turn
+	 * restriction leg with role 'to' was initialized. This is needed if OSM
+	 * data contains turn restrictions with multiple 'to' members. The
+	 * field is null if a turn restriction didn't have a member with role
+	 * 'to'.
+	 */
+	private RelationMember toRelationMember;
+	private Way from;
+	private Way to;
+	private TagCollection tags = new TagCollection();
+	private DataSet dataSet;
+	private final List<OsmPrimitive> vias = new ArrayList<OsmPrimitive>();
+	
+	public TurnRestrictionEditorModel(){
+	}
+	
+	/**
+	 * Sets the way participating in the turn restriction in a given role.
+	 * 
+	 * @param role the role. Must not be null.  
+	 * @param way the way which participates in the turn restriction in the respective role.
+	 * null, to remove the way with the given role.
+	 * @exception IllegalArgumentException thrown if role is null
+	 */
+	public void setTurnRestrictionLeg(TurnRestrictionLegRole role, Way way) {
+		CheckParameterUtil.ensureParameterNotNull(role, "role");
+		Way oldValue = null;
+		switch(role){
+		case FROM: 
+			oldValue = this.from;
+			this.from = way; 
+			break;
+		case TO:
+			oldValue = this.to;
+			this.to = way; 
+			break;
+		}
+		
+		if (oldValue != way) {
+			setChanged();
+			notifyObservers();		
+		}
+	}	
+	
+	/**
+	 * Sets the way participating in the turn restriction in a given role.
+	 * 
+	 * @param role the role. Must not be null.  
+	 * @param wayId the id of the way to set
+	 * @exception IllegalArgumentException thrown if role is null
+	 * @exception IllegalArgumentException thrown if wayId != null isn't the id of a way
+	 * @exception IllegalStateException thrown the no way with this id was found in the dataset 
+	 */
+	public void setTurnRestrictionLeg(TurnRestrictionLegRole role, PrimitiveId wayId) {
+		CheckParameterUtil.ensureParameterNotNull(role, "role");
+		if (wayId == null) {
+			setTurnRestrictionLeg(role, (Way)null);
+			return;
+		}
+		if (!wayId.getType().equals(OsmPrimitiveType.WAY)) {
+			throw new IllegalArgumentException(MessageFormat.format("parameter ''wayId'' of type {0} expected, got {1}", OsmPrimitiveType.WAY, wayId.getType()));
+		}
+		
+		if (dataSet == null) {			
+			throw new IllegalStateException("data set not initialized");			
+		}
+		OsmPrimitive p = dataSet.getPrimitiveById(wayId);
+		if (p == null) {
+			throw new IllegalStateException(MessageFormat.format("didn't find way with id {0} in dataset {1}", wayId, dataSet));			
+		}
+		setTurnRestrictionLeg(role, (Way)p);
+	}	
+	
+	/**
+	 * Replies the turn restrictioin leg with role {@code role}
+	 * 
+	 * @param role the role. Must not be null.
+	 * @return the turn restrictioin leg with role {@code role}. null, if
+	 * no such turn restriction leg exists
+	 * @throws IllegalArgumentException thrown if role is null
+	 */
+	public Way getTurnRestrictionLeg(TurnRestrictionLegRole role){
+		CheckParameterUtil.ensureParameterNotNull(role, "role");
+		switch(role){
+		case FROM: return from;
+		case TO: return to;
+		}
+		return null;
+	}
+	
+	/**
+	 * Initializes the model from a relation representing a turn
+	 * restriction
+	 * 
+	 * @param turnRestriction the turn restriction
+	 */
+	protected void initFromTurnRestriction(Relation turnRestriction) {
+		this.from = null;
+		this.to = null;
+		this.fromRelationMember = null;
+		this.toRelationMember = null;
+		this.tags = new TagCollection();
+		this.vias.clear();
+		if (turnRestriction == null) return;
+		for (RelationMember rm: turnRestriction.getMembers()) {
+			if (rm.getRole().equals("from") && rm.isWay()) {
+				this.fromRelationMember = rm;
+				this.from = rm.getWay();
+				break;
+			}
+		}
+		for (RelationMember rm: turnRestriction.getMembers()) {
+			if (rm.getRole().equals("to") && rm.isWay()) {
+				this.toRelationMember = rm;
+				this.to = rm.getWay();
+				break;
+			}
+		}
+		
+		for (RelationMember rm: turnRestriction.getMembers()) {
+			if (rm.getRole().equals("via")) {
+				this.vias.add(rm.getMember());
+			}
+		}
+		
+		// make sure we have a restriction tag
+		tags = TagCollection.from(turnRestriction);
+		tags.setUniqueForKey("type", "restriction");
+				
+		setChanged();
+		notifyObservers();
+	}
+	
+	/**
+	 * Populates the turn restriction editor model with a turn restriction. 
+	 * {@code turnRestriction} is an arbitrary relation. A tag type=restriction
+	 * isn't required. If it is missing, it is added here. {@code turnRestriction}
+	 * must not be null and it must belong to a dataset. 
+	 * 
+	 * @param turnRestriction the turn restriction
+	 * @throws IllegalArgumentException thrown if turnRestriction is null
+	 * @throws IllegalArgumentException thrown if turnRestriction doesn't belong to a dataset  
+	 */
+	public void populate(Relation turnRestriction) {
+		CheckParameterUtil.ensureParameterNotNull(turnRestriction, "turnRestriction");
+		if (turnRestriction.getDataSet() == null) {			 
+			throw new IllegalArgumentException(
+				// don't translate - it's a technical message
+				MessageFormat.format("turnRestriction {0} must belong to a dataset", turnRestriction.getId())
+			);
+		}
+		this.dataSet = turnRestriction.getDataSet();
+		initFromTurnRestriction(turnRestriction);
+	}
+	
+	/**
+	 * Populates the turn restriction editor model with a new turn restriction,
+	 * which isn't added to a data set yet. {@code ds} is the data set the turn
+	 * restriction is eventually being added to. Relation members of this
+	 * turn restriction must refer to objects in {@code ds}. 
+	 *  
+	 * {@code turnRestriction} is an arbitrary relation. A tag type=restriction
+	 * isn't required. If it is missing, it is added here.  {@code turnRestriction}
+	 * is required to be a new turn restriction with a negative id. It must not be
+	 * part of a dataset yet
+	 * 
+	 * @param turnRestriction the turn restriction. Must not be null. New turn restriction
+	 * required
+	 * @param ds the dataset. Must not be null.
+	 * @throws IllegalArgumentException thrown if turnRestriction is null
+	 * @throws IllegalArgumentException thrown if turnRestriction is part of a dataset
+	 * @throws IllegalArgumentException thrown if turnRestriction isn't a new turn restriction  
+	 */
+	public void populate(Relation turnRestriction, DataSet ds) {
+		CheckParameterUtil.ensureParameterNotNull(turnRestriction, "turnRestriction");
+		CheckParameterUtil.ensureParameterNotNull(ds, "ds");
+		if (!turnRestriction.isNew()){			
+			throw new IllegalArgumentException(
+					// don't translate - it's a technical message
+					MessageFormat.format("new turn restriction expected, got turn restriction with id {0}", turnRestriction.getId())
+			);
+		}
+		if (turnRestriction.getDataSet() != null) {
+			throw new IllegalArgumentException(
+                    // don't translate - it's a technical message
+					MessageFormat.format("expected turn restriction not assigned to a  dataset, got turn restriction with id {0} assigned to {1}", turnRestriction.getId(), turnRestriction.getDataSet())
+			);
+		}
+		for(RelationMember rm: turnRestriction.getMembers()) {
+			if (rm.getMember().getDataSet() != ds) {
+				throw new IllegalArgumentException(
+	                    // don't translate - it's a technical message
+						MessageFormat.format("expected all members assigned to dataset {0}, got member {1} assigned to {2}", ds, rm, rm.getMember().getDataSet())
+				);
+			}
+		}
+		this.dataSet = ds;
+		initFromTurnRestriction(turnRestriction);
+	}
+	
+	/**
+	 * Applies the current state in the model to a turn restriction
+	 * 
+	 * @param turnRestriction the turn restriction. Must not be null.
+	 */
+	public void apply(Relation turnRestriction) {
+		CheckParameterUtil.ensureParameterNotNull(turnRestriction, "turnRestriction");
+		// apply the tags
+		tags.applyTo(turnRestriction);
+		
+		List<RelationMember> members = new ArrayList<RelationMember>();
+		if (from != null){
+			members.add(new RelationMember("from", from));
+		}
+		if (to != null) {
+			members.add(new RelationMember("to", to));			
+		}
+		for(OsmPrimitive via: vias) {
+			members.add(new RelationMember("via", via));
+		}
+		turnRestriction.setMembers(members);
+	}
+	
+	/**
+	 * Replies the current tag value for the tag <tt>restriction</tt>.
+	 * null, if there isn't a tag <tt>restriction</tt>.  
+	 * 
+	 * @return the tag value
+	 */
+	public String getRestrictionTagValue() {
+		if (!tags.hasTagsFor("restriction")) return null;
+		return tags.getJoinedValues("restriction");
+	}
+	
+	/**
+	 * Sets the current value for the restriction tag. If {@code value} is
+	 * null or an empty string, the restriction tag is removed. 
+	 * 
+	 * @param value the value of the restriction tag 
+	 */
+	public void setRestrictionTagValue(String value){
+		if (value == null || value.trim().equals("")) {
+			tags.removeByKey("restriction");
+		} else {
+			tags.setUniqueForKey("restriction", value.trim());
+		}
+		setChanged();
+		notifyObservers();
+	}
+	
+	/**
+	 * Replies the list of 'via' objects. The return value is an
+	 * unmodifiable list.
+	 *  
+	 * @return the list of 'via' objects
+	 */
+	public List<OsmPrimitive> getVias() {
+		return Collections.unmodifiableList(vias);
+	}
+	
+	/**
+	 * Sets the list of vias for the edited turn restriction.
+	 * 
+	 * If {@code vias} is null, all vias are removed. All primitives
+	 * in {@code vias} must be assigned to a dataset and the dataset
+	 * must be equal to the dataset of this editor model, see {@see #getDataSet()}
+	 * 
+	 * @param vias the list of vias 
+	 * @throws IllegalArgumentException thrown if one of the via objects is null or
+	 * if it belongs to the wrong dataset 
+	 */
+	public void setVias(List<OsmPrimitive> vias) {
+		if (vias == null) {
+			this.vias.clear();
+			setChanged();
+			notifyObservers();
+			return;
+		}
+		for (OsmPrimitive p: vias) {
+			if (p == null)
+				throw new IllegalArgumentException("a via object must not be null");
+			if (p.getDataSet() != dataSet)
+				throw new IllegalArgumentException(MessageFormat.format("a via object must belong to dataset {1}, object {2} belongs to {3}", dataSet, p.getPrimitiveId(), p.getDataSet()));
+		}
+		this.vias.clear();
+		this.vias.addAll(vias);
+		setChanged();
+		notifyObservers();
+	}
+	
+	/**
+	 * Replies the dataset this turn restriction editor model is 
+	 * working with
+	 * 
+	 * @return the dataset 
+	 */
+	public DataSet getDataSet() {
+		return this.dataSet;
+	}
+
+	/**
+	 * Registers this model with global event sources like {@see DatasetEventManager}
+	 */
+	public void registerAsEventListener(){
+		DatasetEventManager.getInstance().addDatasetListener(this, FireMode.IN_EDT);
+	}
+	
+	/**
+	 * Removes this model as listener from global event sources like  {@see DatasetEventManager}
+	 */
+	public void unregisterAsEventListener() {
+		DatasetEventManager.getInstance().removeDatasetListener(this);
+	}
+
+	/* ----------------------------------------------------------------------------------------- */
+	/* interface DataSetListener                                                                 */
+	/* ----------------------------------------------------------------------------------------- */
+	
+	protected boolean isAffectedByDataSetUpdate(DataSet ds, List<? extends OsmPrimitive> updatedPrimitives) {
+		if (ds != dataSet) return false;
+		if (updatedPrimitives == null || updatedPrimitives.isEmpty()) return false;
+		if (from != null && updatedPrimitives.contains(from)) return true;
+		if (to != null && updatedPrimitives.contains(to)) return true;
+		for (OsmPrimitive via: vias){
+			if (updatedPrimitives.contains(via)) return true;
+		}
+		return false;
+	}
+	
+	public void dataChanged(DataChangedEvent event) {
+		// refresh the views
+		setChanged();
+		notifyObservers();
+		
+	}
+
+	public void nodeMoved(NodeMovedEvent event) {
+		// may affect the display name of node in the list of vias
+		if (isAffectedByDataSetUpdate(event.getDataset(), event.getPrimitives())) {
+			setChanged();
+			notifyObservers();
+		}
+	}
+
+	public void otherDatasetChange(AbstractDatasetChangedEvent event) {/* irrelevant in this context */}
+
+	public void primtivesAdded(PrimitivesAddedEvent event) {/* irrelevant in this context */}
+	public void primtivesRemoved(PrimitivesRemovedEvent event) {
+		// relevant for the state of this model but not handled here. When the 
+		// state of this model is applied to the dataset we check whether the 
+		// the turn restriction refers to deleted or invisible primitives 
+	}
+
+	public void relationMembersChanged(RelationMembersChangedEvent event) {/* irrelevant in this context */}
+	public void tagsChanged(TagsChangedEvent event) {
+		// may affect the display name of 'from', 'to' or 'via' elements
+		if (isAffectedByDataSetUpdate(event.getDataset(), event.getPrimitives())) {
+			setChanged();
+			notifyObservers();
+		}
+	}
+
+	public void wayNodesChanged(WayNodesChangedEvent event) {
+		// may affect the display name of 'from', 'to' or 'via' elements
+		if (isAffectedByDataSetUpdate(event.getDataset(), event.getPrimitives())) {
+			setChanged();
+			notifyObservers();
+		}		
+	}	
+}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionLegEditor.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionLegEditor.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionLegEditor.java	(revision 20489)
@@ -0,0 +1,360 @@
+package org.openstreetmap.josm.plugins.turnrestrictions.editor;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.BorderLayout;
+import java.awt.Font;
+import java.awt.Image;
+import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.awt.event.ActionEvent;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseMotionAdapter;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Observable;
+import java.util.Observer;
+import java.util.logging.Logger;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.BorderFactory;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.KeyStroke;
+import javax.swing.TransferHandler;
+import javax.swing.UIManager;
+
+import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
+import org.openstreetmap.josm.data.osm.PrimitiveId;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.gui.DefaultNameFormatter;
+import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
+import org.openstreetmap.josm.plugins.turnrestrictions.dnd.PrimitiveIdListProvider;
+import org.openstreetmap.josm.plugins.turnrestrictions.dnd.PrimitiveIdListTransferHandler;
+import org.openstreetmap.josm.plugins.turnrestrictions.dnd.PrimitiveIdTransferable;
+import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Shortcut;
+
+/**
+ * This is an editor for one of the two legs of a turn restriction.
+ */
+public class TurnRestrictionLegEditor extends JPanel implements Observer, PrimitiveIdListProvider {
+	static private final Logger logger = Logger.getLogger(TurnRestrictionLegEditor.class.getName());
+ 
+	private JLabel lblOsmObject;
+	private Way way;
+	private TurnRestrictionEditorModel model;
+	private TurnRestrictionLegRole role; 
+	private DeleteAction actDelete;
+	private CopyAction actCopy;
+	private PasteAction actPaste;
+	private TransferHandler transferHandler;
+	
+	/**
+	 * builds the UI 
+	 */
+	protected void build() {
+		setLayout(new BorderLayout());
+		add(lblOsmObject = new JLabel(), BorderLayout.CENTER);		
+		lblOsmObject.setOpaque(true);
+		lblOsmObject.setBorder(null);
+		setBorder(
+				BorderFactory.createCompoundBorder(
+						BorderFactory.createEtchedBorder(),
+						BorderFactory.createEmptyBorder(1,1,1,1)
+				)
+		);
+		
+		JButton btn;
+		actDelete = new DeleteAction();
+		add(btn = new JButton(actDelete), BorderLayout.EAST);
+		btn.setFocusable(false);
+		btn.setText(null);
+		btn.setBorder(BorderFactory.createRaisedBevelBorder());
+				
+		// focus handling
+		FocusHandler fh  = new FocusHandler();
+		lblOsmObject.setFocusable(true);	
+		lblOsmObject.addFocusListener(fh);		
+		this.addFocusListener(fh);
+
+		// mouse event handling
+		MouseEventHandler meh = new MouseEventHandler();
+		lblOsmObject.addMouseListener(meh);
+		addMouseListener(meh);
+		lblOsmObject.addMouseListener(new PopupLauncher());
+		
+		// enable DEL to remove the object from the turn restriction
+		registerKeyboardAction(actDelete,KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,0) , JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
+
+		getInputMap().put(Shortcut.getCopyKeyStroke(), TransferHandler.getCopyAction().getValue(Action.NAME));;
+		getInputMap().put(Shortcut.getPasteKeyStroke(), TransferHandler.getPasteAction().getValue(Action.NAME));;
+		getActionMap().put(TransferHandler.getCopyAction().getValue(Action.NAME), TransferHandler.getCopyAction());
+		getActionMap().put(TransferHandler.getPasteAction().getValue(Action.NAME), TransferHandler.getPasteAction());
+		lblOsmObject.setTransferHandler(transferHandler = new LegEditorTransferHandler(this));
+		lblOsmObject.addMouseMotionListener(new MouseMotionAdapter(){
+			@Override
+			public void mouseDragged(MouseEvent e) {
+				JComponent c = (JComponent)e.getSource();
+				TransferHandler th = c.getTransferHandler();
+				th.exportAsDrag(c, e, TransferHandler.COPY);				
+			}					
+		});
+		actCopy = new CopyAction();
+		actPaste = new PasteAction();
+	}
+	
+	/**
+	 * Constructor 
+	 * 
+	 * @param model the model. Must not be null.
+	 * @param role the leg role of the leg this editor is editing. Must not be null.
+	 * @exception IllegalArgumentException thrown if model is null
+	 * @exception IllegalArgumentException thrown if role is null
+	 */
+	public TurnRestrictionLegEditor(TurnRestrictionEditorModel model, TurnRestrictionLegRole role) {
+		CheckParameterUtil.ensureParameterNotNull(model, "model");
+		CheckParameterUtil.ensureParameterNotNull(role, "role");
+		
+		this.model = model;
+		this.role = role;
+		build();
+		model.addObserver(this);
+		refresh();	
+	}
+
+	protected void refresh(){
+		Way newWay = model.getTurnRestrictionLeg(role);
+		way = newWay;
+		if (way == null) {
+			lblOsmObject.setFont(UIManager.getFont("Label.font").deriveFont(Font.ITALIC));
+			lblOsmObject.setIcon(null);
+			lblOsmObject.setText(tr("please select a way"));
+			lblOsmObject.setToolTipText(null);
+		} else {
+			lblOsmObject.setFont(UIManager.getFont("Label.font"));
+			lblOsmObject.setIcon(ImageProvider.get("data", "way"));
+			lblOsmObject.setText(DefaultNameFormatter.getInstance().format(way));
+			lblOsmObject.setToolTipText(DefaultNameFormatter.getInstance().buildDefaultToolTip(way));
+		}
+		renderColors();
+		actDelete.updateEnabledState();
+	}
+	
+	/**
+	 * Render the foreground and background color
+	 */
+	protected void renderColors() {
+		if (lblOsmObject.hasFocus()) {
+			setBackground(UIManager.getColor("List.selectionBackground"));
+			setForeground(UIManager.getColor("List.selectionForeground"));
+			lblOsmObject.setBackground(UIManager.getColor("List.selectionBackground"));
+			lblOsmObject.setForeground(UIManager.getColor("List.selectionForeground"));
+		} else {
+			lblOsmObject.setBackground(UIManager.getColor("List.background"));
+			lblOsmObject.setForeground(UIManager.getColor("List.foreground"));
+		}
+	}
+	
+	/**
+	 * Replies the model for this editor
+	 * 
+	 * @return the model 
+	 */
+	public TurnRestrictionEditorModel getModel() {
+		return model;
+	}
+	
+	/**
+	 * Replies the role of this editor 
+	 * 
+	 * @return the role 
+	 */
+	public TurnRestrictionLegRole getRole() {
+		return role;
+	}		
+
+	/* ----------------------------------------------------------------------------- */
+	/* interface Observer                                                            */
+	/* ----------------------------------------------------------------------------- */
+	public void update(Observable o, Object arg) {
+		refresh();		
+	}
+	
+	/* ----------------------------------------------------------------------------- */
+	/* interface PrimitiveIdListProvider                                                            */
+	/* ----------------------------------------------------------------------------- */
+	public List<PrimitiveId> getSelectedPrimitiveIds() {
+		if (way == null) return Collections.emptyList();
+		return Collections.singletonList(way.getPrimitiveId());
+	}
+	
+	/* ----------------------------------------------------------------------------- */
+	/* inner classes                                                                 */
+	/* ----------------------------------------------------------------------------- */	
+	/**
+	 * Responds to focus change events  
+	 */
+	class FocusHandler extends FocusAdapter {
+		@Override
+		public void focusGained(FocusEvent e) {
+			renderColors();
+		}
+
+		@Override
+		public void focusLost(FocusEvent e) {
+			renderColors();
+		}		
+	}
+	
+	class MouseEventHandler extends MouseAdapter {
+		@Override
+		public void mouseClicked(MouseEvent e) {
+			lblOsmObject.requestFocusInWindow();
+		}		
+	}
+	
+	/**
+	 * Deletes the way from the turn restriction 
+	 */
+	class DeleteAction extends AbstractAction {
+		public DeleteAction() {
+			putValue(SHORT_DESCRIPTION, tr("Delete from turn restriction"));
+			putValue(NAME, tr("Delete"));
+			putValue(SMALL_ICON, ImageProvider.get("deletesmall"));
+			putValue(ACCELERATOR_KEY,KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,0));
+			updateEnabledState();
+		}
+		
+		public void actionPerformed(ActionEvent e) {
+			model.setTurnRestrictionLeg(role, null);			
+		}		
+		
+		public void updateEnabledState() {
+			setEnabled(way != null);
+		}
+	}
+	
+	/**
+	 * The transfer handler for Drag-and-Drop. 
+	 */
+	class LegEditorTransferHandler extends PrimitiveIdListTransferHandler {
+		Logger logger = Logger.getLogger(LegEditorTransferHandler.class.getName());
+		
+		public LegEditorTransferHandler(PrimitiveIdListProvider provider){
+			super(provider);
+		}
+
+		@SuppressWarnings("unchecked")
+		@Override
+		public boolean importData(JComponent comp, Transferable t) {
+			try {
+				List<PrimitiveId> ids = (List<PrimitiveId>)t.getTransferData(PrimitiveIdTransferable.PRIMITIVE_ID_LIST_FLAVOR);
+				if (ids.size() !=1) {
+					return false;
+				}
+				PrimitiveId id = ids.get(0);
+				if (!id.getType().equals(OsmPrimitiveType.WAY)) return false;
+				model.setTurnRestrictionLeg(role, id);
+				return true;
+			} catch(IOException e) {
+				// ignore
+				return false;
+			} catch(UnsupportedFlavorException e) {
+				// ignore
+				return false;
+			}
+		}
+
+		@Override
+		protected Transferable createTransferable(JComponent c) {
+			if (way == null) return null;
+			return super.createTransferable(c);
+		}
+	}
+	
+	class PopupLauncher extends PopupMenuLauncher {
+		@Override
+		public void launch(MouseEvent evt) {
+			new PopupMenu().show(lblOsmObject, evt.getX(), evt.getY());
+		}		
+	}
+	
+	class PopupMenu extends JPopupMenu {
+		public PopupMenu() {
+			actCopy.updateEnabledState();
+			JMenuItem item = add(actCopy);
+			item.setTransferHandler(transferHandler);
+			actPaste.updateEnabledState();
+			item = add(actPaste);			
+			item.setTransferHandler(transferHandler);
+			addSeparator();
+			add(actDelete);
+		}
+	}
+	
+	class CopyAction extends AbstractAction {
+		private Action delegate;
+		
+		public CopyAction(){
+			putValue(NAME, tr("Copy"));
+			putValue(SHORT_DESCRIPTION, tr("Copy to the clipboard"));
+			putValue(SMALL_ICON, ImageProvider.get("copy"));
+			putValue(ACCELERATOR_KEY, Shortcut.getCopyKeyStroke());
+			delegate = TurnRestrictionLegEditor.this.getActionMap().get("copy");
+			updateEnabledState();
+		}
+
+		public void actionPerformed(ActionEvent e) {
+			delegate.actionPerformed(e);
+		}
+		
+		public void updateEnabledState() {
+			setEnabled(way != null);
+		}
+	}
+	
+	class PasteAction extends AbstractAction {
+		private Action delegate;
+		
+		public boolean canPaste() {
+			Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
+			for (DataFlavor df: clipboard.getAvailableDataFlavors()) {
+				if (df.equals(PrimitiveIdTransferable.PRIMITIVE_ID_LIST_FLAVOR)) return true;
+			}			
+			// FIXME: check whether there are selected objects in the JOSM copy/paste buffer  
+			return false;
+		}
+		
+		public PasteAction(){
+			putValue(NAME, tr("Paste"));
+			putValue(SHORT_DESCRIPTION, tr("Paste from the clipboard"));
+			putValue(SMALL_ICON, ImageProvider.get("paste"));
+			putValue(ACCELERATOR_KEY, Shortcut.getPasteKeyStroke());
+			delegate = TurnRestrictionLegEditor.this.getActionMap().get("paste");
+		}
+		
+		public void updateEnabledState() {
+			setEnabled(canPaste());
+		}
+
+		public void actionPerformed(ActionEvent e) {
+			delegate.actionPerformed(e);			
+		}
+	}
+}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionLegRole.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionLegRole.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionLegRole.java	(revision 20489)
@@ -0,0 +1,9 @@
+package org.openstreetmap.josm.plugins.turnrestrictions.editor;
+
+/**
+ * Enumerates the two roles a "leg" in a turn restriction can have.
+ */
+public enum TurnRestrictionLegRole {	
+	FROM,
+	TO
+}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionType.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionType.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionType.java	(revision 20489)
@@ -0,0 +1,58 @@
+package org.openstreetmap.josm.plugins.turnrestrictions.editor;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+/**
+ * This is the enumeration of turn restriction types, see 
+ * <a href="http://wiki.openstreetmap.org/wiki/Turn_restriction">OSM Wiki</a>
+ * 
+ */
+public enum TurnRestrictionType {
+	NO_RIGHT_TURN("no_right_turn", tr("No Right Turn")),
+	NO_LEFT_TURN("no_left_turn", tr("No Left Turn")),
+	NO_U_TURN("no_u_turn", tr("No U-Turn")),
+	NO_STRAIGHT_ON("no_straight_on", tr("No Straight On")),	
+	ONLY_RIGHT_TURN("only_right_turn", tr("Only Right Turn")),
+	ONLY_LEFT_TURN("only_left_turn", tr("Only Left Turn")),
+	ONLY_STRAIGHT_ON("only_straight_on", tr("Only Straight On"));
+	
+	private String tagValue;
+	private String displayName;
+	
+	TurnRestrictionType(String tagValue, String displayName) {
+		this.tagValue = tagValue;
+		this.displayName = displayName;
+	}
+	
+	/**
+	 * Replies the tag value for a specific turn restriction type
+	 * 
+	 * @return the tag value for a specific turn restriction type
+	 */
+	public String getTagValue() {
+		return tagValue;
+	}
+	
+	/**
+	 * Replies the localized display name for a turn restriction type
+	 */
+	public String getDisplayName() {
+		return displayName;
+	}	
+	
+	/**
+	 * Replies the enumeration value for a given tag value. null,
+	 * if {@code tagValue} is null or if there isnt an enumeration value
+	 * for this {@code tagValue}
+	 *  
+	 * @param tagValue the tag value, i.e. <tt>no_left_turn</tt>
+	 * @return the enumeration value
+	 */
+	static public TurnRestrictionType fromTagValue(String tagValue) {
+		if (tagValue == null) return null;
+		for(TurnRestrictionType type: values()) {
+			if(type.getTagValue().equals(tagValue)) return type;
+		}
+		return null;
+	}
+}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionTypeRenderer.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionTypeRenderer.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionTypeRenderer.java	(revision 20489)
@@ -0,0 +1,69 @@
+package org.openstreetmap.josm.plugins.turnrestrictions.editor;
+
+import java.awt.Component;
+import java.awt.Image;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.swing.ImageIcon;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.ListCellRenderer;
+import javax.swing.UIManager;
+
+import org.openstreetmap.josm.tools.ImageProvider;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+
+public class TurnRestrictionTypeRenderer extends JLabel implements ListCellRenderer{
+ 
+	final private Map<TurnRestrictionType, ImageIcon> icons = new HashMap<TurnRestrictionType, ImageIcon>();
+	
+	/**
+	 * Loads the image icons for the rendered turn restriction types 
+	 */
+	protected void loadImages() {
+		for(TurnRestrictionType type: TurnRestrictionType.values()) {
+			try {
+				ImageIcon icon = new ImageIcon(ImageProvider.get("types", type.getTagValue()).getImage().getScaledInstance(16, 16, Image.SCALE_SMOOTH));
+				icons.put(type,icon);
+			} catch(Exception e){
+				System.out.println(tr("Warning: failed to load icon for turn restriction type ''{0}''", type.getTagValue()));
+				e.printStackTrace();				
+			}
+		}
+	}
+	
+	public TurnRestrictionTypeRenderer() {
+		setOpaque(true);
+		loadImages();
+	}
+	
+	protected void renderColors(boolean isSelected){
+		if (isSelected){
+			setBackground(UIManager.getColor("List.selectionBackground"));
+			setForeground(UIManager.getColor("List.selectionForeground"));
+		} else {
+			setBackground(UIManager.getColor("List.background"));
+			setForeground(UIManager.getColor("List.foreground"));			
+		}
+	}
+	
+	public Component getListCellRendererComponent(JList list, Object value,
+			int index, boolean isSelected, boolean cellHasFocus) {
+		
+		renderColors(isSelected);
+		if (value == null) {
+			setText(tr("please select a turn restriction type"));
+			setIcon(null);
+		} else if (value instanceof String){
+			setText((String)value);
+			setIcon(null); // FIXME: special icon for non-standard types? 
+		} else if (value instanceof TurnRestrictionType){
+			TurnRestrictionType type = (TurnRestrictionType)value;
+			setText(type.getDisplayName());
+			setIcon(icons.get(type));
+		}
+		return this;
+	}	
+}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/ViaList.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/ViaList.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/ViaList.java	(revision 20489)
@@ -0,0 +1,307 @@
+package org.openstreetmap.josm.plugins.turnrestrictions.editor;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.awt.event.ActionEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.io.IOException;
+import java.util.List;
+import java.util.logging.Logger;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.DefaultListSelectionModel;
+import javax.swing.JComponent;
+import javax.swing.JList;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.KeyStroke;
+import javax.swing.ListSelectionModel;
+import javax.swing.TransferHandler;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+import org.openstreetmap.josm.data.osm.PrimitiveId;
+import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
+import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
+import org.openstreetmap.josm.plugins.turnrestrictions.dnd.PrimitiveIdListProvider;
+import org.openstreetmap.josm.plugins.turnrestrictions.dnd.PrimitiveIdListTransferHandler;
+import org.openstreetmap.josm.plugins.turnrestrictions.dnd.PrimitiveIdTransferable;
+import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Shortcut;
+
+/**
+ * ViaList is a JList which displays the 'via' members of a turn restriction.
+ * 
+ * A ViaList is connected to a {@see TurnRestrictionEditorModel} through its
+ * {@code ViaListModel}. 
+ * 
+ */
+public class ViaList extends JList{
+	
+	static private final Logger logger = Logger.getLogger(ViaList.class.getName());
+
+	private ViaListModel model;
+	private DeleteAction actDelete;
+	private MoveUpAction actMoveUp;
+	private MoveDownAction actMoveDown;
+	private CopyAction actCopy;
+	private PasteAction actPaste;
+	private TransferHandler transferHandler;
+	
+	/**
+	 * Constructor 
+	 * 
+	 * @param model the via list model. Must not be null.
+	 * @param selectionModel the selection model. Must not be null.
+	 * 
+	 */
+	public ViaList(ViaListModel model, DefaultListSelectionModel selectionModel) {
+		super(model);
+		this.model = model;
+		setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+		setSelectionModel(selectionModel);
+		setCellRenderer(new OsmPrimitivRenderer());
+		setDragEnabled(true);		
+		setTransferHandler(transferHandler =new ViaListTransferHandler(model));
+		setVisibleRowCount(4);
+		
+		actDelete = new DeleteAction();
+		selectionModel.addListSelectionListener(actDelete);
+		registerKeyboardAction(actDelete, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
+		
+		actMoveDown = new MoveDownAction();
+		selectionModel.addListSelectionListener(actMoveDown);
+		registerKeyboardAction(actMoveDown, KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, KeyEvent.ALT_DOWN_MASK), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
+
+		actMoveUp = new MoveUpAction();
+		selectionModel.addListSelectionListener(actMoveUp);
+		registerKeyboardAction(actMoveUp, KeyStroke.getKeyStroke(KeyEvent.VK_UP, KeyEvent.ALT_DOWN_MASK), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
+		
+		actCopy = new CopyAction();
+		actPaste = new PasteAction();
+		getSelectionModel().addListSelectionListener(actCopy);
+        
+		addMouseListener(new ViaListPopupMenuLaucher());			
+	}
+	
+	/**
+	 * The transfer handler for Drag-and-Drop. 
+	 */
+	class ViaListTransferHandler extends PrimitiveIdListTransferHandler {
+		Logger logger = Logger.getLogger(ViaListTransferHandler.class.getName());
+		
+		private boolean isViaListInDragOperation = false;
+		private List<Integer> selectedRowsMemento = null;
+		
+		public ViaListTransferHandler(PrimitiveIdListProvider provider) {
+			super(provider);
+		}
+
+		@Override
+		public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
+			// a drag operation on itself is always allowed
+			if (isViaListInDragOperation) return true;
+			return isSupportedFlavor(transferFlavors);			
+		}
+
+		@SuppressWarnings("unchecked")
+		@Override
+		public boolean importData(JComponent comp, Transferable t) {	
+			if (!isSupportedFlavor(t.getTransferDataFlavors())) return false;
+			if (isViaListInDragOperation) {
+				// this is a drag operation on itself
+				int targetRow = getSelectedIndex();
+				if (targetRow <0) return true;
+				model.moveVias(selectedRowsMemento, targetRow);				
+			} else {
+				// this is a drag operation from another component
+				try {
+					List<PrimitiveId> idsToAdd = (List<PrimitiveId>)t.getTransferData(PrimitiveIdTransferable.PRIMITIVE_ID_LIST_FLAVOR);
+					model.insertVias(idsToAdd);
+				} catch(IOException e){
+					e.printStackTrace();
+				} catch(UnsupportedFlavorException e){
+					e.printStackTrace();
+				}
+			}
+			return true;
+		}
+
+		@Override
+		protected void exportDone(JComponent source, Transferable data, int action) {
+			isViaListInDragOperation = false;
+			super.exportDone(source, data, action);
+		}
+
+		@Override
+		public void exportAsDrag(JComponent comp, InputEvent e, int action) {
+			isViaListInDragOperation = true;
+			selectedRowsMemento = model.getSelectedRows();
+			super.exportAsDrag(comp, e, action);
+		}		
+	}	
+	
+	class DeleteAction extends AbstractAction implements ListSelectionListener {
+		public DeleteAction() {
+			putValue(NAME, tr("Remove"));
+			putValue(SMALL_ICON, ImageProvider.get("dialogs", "delete"));
+			putValue(SHORT_DESCRIPTION,tr("Remove the currently selected vias"));		
+			putValue(ACCELERATOR_KEY,KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,0));			
+			updateEnabledState();
+		}
+		
+		public void valueChanged(ListSelectionEvent e) {
+			updateEnabledState();			
+		}
+		
+		public void updateEnabledState() {
+			setEnabled(getSelectedIndex() >= 0);
+		}
+
+		public void actionPerformed(ActionEvent e) {
+			model.removeSelectedVias();			
+		}
+	}
+	
+	class MoveDownAction extends AbstractAction implements ListSelectionListener{		
+		public MoveDownAction(){
+			putValue(NAME, tr("Move down"));
+			putValue(SHORT_DESCRIPTION, tr("Move the selected vias down by one position"));
+			putValue(ACCELERATOR_KEY,KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, KeyEvent.ALT_DOWN_MASK));
+			putValue(SMALL_ICON, ImageProvider.get("dialogs", "movedown"));
+			updateEnabledState();
+		}
+		
+		public void actionPerformed(ActionEvent e) {
+			model.moveDown();
+		}
+
+		public void updateEnabledState(){
+			if (getSelectedIndex() < 0) {
+				setEnabled(false);
+				return;
+			}
+			setEnabled(getSelectionModel().getMaxSelectionIndex() < getModel().getSize() -1);
+		}
+		
+		public void valueChanged(ListSelectionEvent e) {
+			updateEnabledState();			
+		}
+	}
+	
+	class MoveUpAction extends AbstractAction implements ListSelectionListener{		
+		public MoveUpAction() {
+			putValue(NAME, tr("Move up"));
+			putValue(SHORT_DESCRIPTION, tr("Move the selected vias up by one position"));
+			putValue(ACCELERATOR_KEY,KeyStroke.getKeyStroke(KeyEvent.VK_UP, KeyEvent.ALT_DOWN_MASK));
+			putValue(SMALL_ICON, ImageProvider.get("dialogs", "moveup"));
+			updateEnabledState();
+		}
+		
+		public void actionPerformed(ActionEvent e) {
+			model.moveUp();
+		}
+
+		public void updateEnabledState(){
+			if (getSelectedIndex() < 0) {
+				setEnabled(false);
+				return;
+			}
+			setEnabled(getSelectionModel().getMinSelectionIndex() > 0);
+		}
+		
+		public void valueChanged(ListSelectionEvent e) {
+			updateEnabledState();			
+		}
+	}
+
+	class CopyAction extends AbstractAction implements ListSelectionListener {
+		private Action delegate;
+		
+		public CopyAction(){
+			putValue(NAME, tr("Copy"));
+			putValue(SHORT_DESCRIPTION, tr("Copy the selected vias to the clipboard"));
+			putValue(SMALL_ICON, ImageProvider.get("copy"));
+			putValue(ACCELERATOR_KEY, Shortcut.getCopyKeyStroke());
+			delegate = ViaList.this.getActionMap().get("copy");
+		}
+
+		public void actionPerformed(ActionEvent e) {			
+			delegate.actionPerformed(e);
+		}
+
+		protected void updateEnabledState() {
+			setEnabled(!model.getSelectedVias().isEmpty());
+		}
+		
+		public void valueChanged(ListSelectionEvent e) {
+			updateEnabledState();
+		}
+	}
+	
+	class PasteAction extends AbstractAction {
+		private Action delegate;
+		
+		public boolean canPaste() {
+			Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
+			for (DataFlavor df: clipboard.getAvailableDataFlavors()) {
+				if (df.equals(PrimitiveIdTransferable.PRIMITIVE_ID_LIST_FLAVOR)) return true;
+			}			
+			// FIXME: check whether there are selected objects in the JOSM copy/paste buffer  
+			return false;
+		}
+		
+		public PasteAction(){
+			putValue(NAME, tr("Paste"));
+			putValue(SHORT_DESCRIPTION, tr("Insert 'via' objects from the clipboard"));
+			putValue(SMALL_ICON, ImageProvider.get("paste"));
+			putValue(ACCELERATOR_KEY, Shortcut.getPasteKeyStroke());
+			delegate = ViaList.this.getActionMap().get("paste");
+			updateEnabledState();
+		}
+
+		public void updateEnabledState() {
+			setEnabled(canPaste());
+		}
+		
+		public void actionPerformed(ActionEvent e) {
+			delegate.actionPerformed(e);			
+		}
+	}
+	
+	class ViaListPopupMenu extends JPopupMenu {
+		public ViaListPopupMenu() {
+			JMenuItem item = add(actCopy);
+			item.setTransferHandler(transferHandler);			
+			item = add(actPaste);
+			actPaste.updateEnabledState();
+			item.setTransferHandler(transferHandler);
+			addSeparator();
+			add(actDelete);
+			addSeparator();
+			add(actMoveUp);
+			add(actMoveDown);
+		}
+	}
+	
+	class ViaListPopupMenuLaucher extends PopupMenuLauncher {
+		@Override
+		public void launch(MouseEvent evt) {
+			if (getSelectedIndex() <0) {
+				int idx = locationToIndex(evt.getPoint());
+				if (idx >=0) {
+					setSelectedIndex(idx);
+				}
+			}
+			new ViaListPopupMenu().show(ViaList.this, evt.getX(), evt.getY());
+		}		
+	}	
+}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/ViaListModel.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/ViaListModel.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/ViaListModel.java	(revision 20489)
@@ -0,0 +1,245 @@
+package org.openstreetmap.josm.plugins.turnrestrictions.editor;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Observable;
+import java.util.Observer;
+import java.util.logging.Logger;
+
+import javax.swing.AbstractListModel;
+import javax.swing.DefaultListSelectionModel;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.PrimitiveId;
+import org.openstreetmap.josm.plugins.turnrestrictions.dnd.PrimitiveIdListProvider;
+import org.openstreetmap.josm.tools.CheckParameterUtil;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+/**
+ * ViaListModel is a model for the list of 'via' objects of a turn restriction.
+ * 
+ */
+public class ViaListModel extends AbstractListModel implements PrimitiveIdListProvider, Observer{
+	static private final Logger logger = Logger.getLogger(ViaListModel.class.getName());
+	
+	private DefaultListSelectionModel selectionModel;
+	private final ArrayList<OsmPrimitive> vias = new ArrayList<OsmPrimitive>();
+	private TurnRestrictionEditorModel model;
+	
+	/**
+	 * Constructor 
+	 * 
+	 * @param model the turn restriction editor model. Must not be null.
+	 * @param selectionModel the selection model. Must not be null.
+	 * @throws IllegalArgumentException thrown if model is null
+	 * @throws IllegalArgumentException thrown if selectionModel is null
+	 */
+	public ViaListModel(TurnRestrictionEditorModel model, DefaultListSelectionModel selectionModel) {
+		CheckParameterUtil.ensureParameterNotNull(model, "model");
+		CheckParameterUtil.ensureParameterNotNull(selectionModel, "selectionModel");
+		this.model = model;
+		this.selectionModel = selectionModel;
+		model.addObserver(this);
+		refresh();
+	}
+
+	/**
+	 * Replies the list of currently selected vias
+	 * 
+	 * @return the list of currently selected vias
+	 */
+	public List<OsmPrimitive> getSelectedVias() {
+		ArrayList<OsmPrimitive> ret = new ArrayList<OsmPrimitive>();
+		for (int i=0; i < getSize(); i++) {
+			if (selectionModel.isSelectedIndex(i)) {
+				ret.add(vias.get(i));
+			}
+		}
+		return ret;
+	}
+	
+	/**
+	 * Sets the collection of currently selected vias
+	 * 
+	 *  @param vias a collection of vias 
+	 */
+	public void setSelectedVias(Collection<OsmPrimitive> vias) {
+		selectionModel.clearSelection();
+		if (vias == null) return;
+		for(OsmPrimitive via: vias) {
+			int idx = this.vias.indexOf(via);
+			if (idx < 0) continue;
+			selectionModel.addSelectionInterval(idx, idx);
+		}
+	}
+	
+	/**
+	 * Replies the list of selected rows 
+	 * 
+	 * @return the list of selected rows
+	 */
+	public List<Integer> getSelectedRows() {
+		ArrayList<Integer> ret = new ArrayList<Integer>();
+		for (int i=0; i < getSize(); i++) {
+			if (selectionModel.isSelectedIndex(i)) {
+				ret.add(i);
+			}
+		}
+		return ret;
+	}
+	
+	protected List<Integer> moveUp(List<Integer> rows, int targetRow) {
+		List<Integer> ret = new ArrayList<Integer>(rows.size());
+		int delta = rows.get(0) - targetRow;
+		for(int row: rows) {
+			OsmPrimitive via = vias.remove(row);
+			vias.add(row - delta, via);
+			ret.add(row - delta);
+		}
+		return ret;
+	}
+	
+	protected List<Integer>  moveDown(List<Integer> rows, int targetRow) {
+		List<Integer> ret = new ArrayList<Integer>(rows.size());
+		int delta = targetRow - rows.get(0);
+		for(int i = rows.size()-1; i >=0; i--) {
+			int row = rows.get(i);
+			OsmPrimitive via = vias.remove(row);
+			vias.add(row + delta, via);
+			ret.add(row + delta);
+		}
+		return ret;
+	}
+	
+	public void moveVias(List<Integer> selectedRows, int targetRow){
+		if (selectedRows == null) return;
+		if (selectedRows.size() == 1){
+			int sourceRow = selectedRows.get(0);
+			if (sourceRow == targetRow) return;
+			OsmPrimitive via = vias.remove(sourceRow);
+			vias.add(targetRow, via);
+			fireContentsChanged(this, 0, getSize());
+			selectionModel.setSelectionInterval(targetRow, targetRow);
+			return;
+		} 
+		int min = selectedRows.get(0);
+		int max = selectedRows.get(selectedRows.size()-1);
+		if (targetRow < min) {
+			selectedRows = moveUp(selectedRows, targetRow);
+		} else if (targetRow == min){
+			// do nothing
+		} else if (targetRow - min < getSize() - max){
+			int delta = Math.min(targetRow - min, getSize()-1 - max);
+			targetRow = min + delta;
+			if (targetRow > min) {
+				selectedRows = moveDown(selectedRows, targetRow);
+			}
+		} 
+		fireContentsChanged(this, 0, getSize());
+		selectionModel.clearSelection();
+		for(int row: selectedRows) {
+			selectionModel.addSelectionInterval(row, row);
+		}		
+	}
+	
+	/**
+	 * Move the currently selected vias up by one position
+	 */
+	public void moveUp() {
+		List<Integer> sel = getSelectedRows();
+		if (sel.isEmpty() || sel.get(0) == 0) return;
+		moveVias(sel, sel.get(0)-1);
+	}
+
+	/**
+	 * Move the currently selected vias down by one position
+	 */
+	public void moveDown() {
+		List<Integer> sel = getSelectedRows();
+		if (sel.isEmpty() || sel.get(sel.size()-1) == getSize()-1) return;
+		moveVias(sel, sel.get(sel.size()-1)+1);
+	}
+	
+	/**
+	 * Inserts a list of OSM objects given by OSM primitive ids. 
+	 * 
+	 * @param idsToInsert the ids of the objects to insert
+	 */
+	public void insertVias(List<PrimitiveId> idsToInsert) {
+		if (idsToInsert == null) return;
+		List<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>(idsToInsert.size());
+		DataSet ds = model.getDataSet();
+		for(PrimitiveId id: idsToInsert){
+			OsmPrimitive p = ds.getPrimitiveById(id);
+			if (p == null){
+				System.out.println(tr("Failed to retrieve OSM object with id {0} from dataset {1}. Cannot add it as ''via''.", id, ds));
+				continue;
+			}
+			primitives.add(p);
+		}
+		int targetRow = Math.max(selectionModel.getMinSelectionIndex(),0);
+		List<OsmPrimitive> newVias = new ArrayList<OsmPrimitive>(vias);
+		newVias.addAll(targetRow, primitives);
+		model.setVias(newVias);
+		fireContentsChanged(this, 0, getSize());
+		selectionModel.clearSelection();
+		for(int i=targetRow; i< targetRow + primitives.size();i++) {
+			selectionModel.addSelectionInterval(i, i);
+		}			
+	}
+
+	/**
+	 * Removes the currently selected vias
+	 */
+	public void removeSelectedVias() {
+		ArrayList<OsmPrimitive> newVias = new ArrayList<OsmPrimitive>(vias);
+		int j = 0;
+		for(int i=0; i< getSize();i++){
+			if (!selectionModel.isSelectedIndex(i)) continue;
+			newVias.remove(i-j);
+			j++;
+		}
+		if (j == 0) return; // nothing selected, nothing deleted
+		model.setVias(newVias);
+	}
+	
+	/**
+	 * Refreshes the list of 'vias' in this model with the current list of
+	 * vias from the turn restriction model. 
+	 */
+	protected void refresh() {
+		List<OsmPrimitive> sel = getSelectedVias();
+		vias.clear();
+		vias.addAll(model.getVias());		
+		fireContentsChanged(this, 0, getSize());
+		setSelectedVias(sel);
+	}
+
+	public Object getElementAt(int index) {
+		return vias.get(index);
+	}
+
+	public int getSize() {
+		return vias.size();
+	}
+	
+	/* ----------------------------------------------------------------------- */
+	/* interface PrimitiveIdListProvider                                       */
+	/* ----------------------------------------------------------------------- */
+	public List<PrimitiveId> getSelectedPrimitiveIds() {
+		ArrayList<PrimitiveId> ids = new ArrayList<PrimitiveId>();
+		for (OsmPrimitive p: getSelectedVias()) {
+			ids.add(p.getPrimitiveId());
+		}
+		return ids;
+	}
+
+	/* ----------------------------------------------------------------------- */
+	/* interface Observer                                                      */
+	/* ----------------------------------------------------------------------- */
+	public void update(Observable o, Object arg) {
+		refresh();
+	}	
+}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/AbstractTurnRestrictionsListView.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/AbstractTurnRestrictionsListView.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/AbstractTurnRestrictionsListView.java	(revision 20489)
@@ -0,0 +1,34 @@
+package org.openstreetmap.josm.plugins.turnrestrictions.list;
+
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.event.ListSelectionListener;
+
+/**
+ * The abstract base class for two views of turn restriction lists.
+ * 
+ * @see TurnRestrictionsInSelectionView
+ * @see TurnRestrictionsInDatasetView
+ *
+ */
+abstract class AbstractTurnRestrictionsListView extends JPanel {
+	protected TurnRestrictionsListModel model;
+	protected JList lstTurnRestrictions;
+	
+	public TurnRestrictionsListModel getModel(){
+		return model;
+	}
+	
+	public JList getList() {
+		return lstTurnRestrictions;
+	}
+	
+	public void addListSelectionListener(ListSelectionListener listener) {
+		lstTurnRestrictions.addListSelectionListener(listener);
+	}
+	 
+	public void removeListSelectionListener(ListSelectionListener listener) {
+		lstTurnRestrictions.addListSelectionListener(listener);
+	}
+
+}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionListCellRenderer.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionListCellRenderer.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionListCellRenderer.java	(revision 20489)
@@ -0,0 +1,221 @@
+package org.openstreetmap.josm.plugins.turnrestrictions.list;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.swing.ImageIcon;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.ListCellRenderer;
+import javax.swing.UIManager;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.gui.DefaultNameFormatter;
+import org.openstreetmap.josm.gui.JMultilineLabel;
+import org.openstreetmap.josm.tools.ImageProvider;
+
+/**
+ * This the cell renderer for turn restrictions in the turn restriction list
+ * dialog.
+ *
+ */
+public class TurnRestrictionListCellRenderer extends JPanel implements ListCellRenderer{
+
+	/** the names of restriction types */
+	static private Set<String> RESTRICTION_TYPES = new HashSet<String>(
+			Arrays.asList(new String[] {
+					"no_left_turn",
+					"no_right_turn",
+					"no_straight_on",
+					"no_u_turn",
+					"only_left_turn",
+					"only_right_turn",
+					"only_straight_on"
+			})
+	);
+	
+	/** components used to render the turn restriction */
+	private JLabel icon;
+	private JLabel from;
+	private JLabel to;
+	
+	public TurnRestrictionListCellRenderer() {
+		build();
+	}
+
+	/**
+	 * Replies true if {@code restrictionType} is a valid restriction
+	 * type.
+	 * 
+	 * @param restrictionType the restriction type 
+	 * @return true if {@code restrictionType} is a valid restriction
+	 * type
+	 */
+	protected boolean isValidRestrictionType(String restrictionType) {
+		if (restrictionType == null) return false;
+		restrictionType = restrictionType.trim().toLowerCase();
+		return RESTRICTION_TYPES.contains(restrictionType);
+	}
+	
+	/**
+	 * Builds the icon name for a given restriction type 
+	 * 
+	 * @param restrictionType the restriction type 
+	 * @return the icon name 
+	 */
+	protected String buildImageName(String restrictionType) {
+		return "types/" + restrictionType;
+	}
+	
+	/**
+	 * Replies the icon for a given restriction type 
+	 * @param restrictionType the restriction type 
+	 * @return the icon 
+	 */
+	protected ImageIcon getIcon(String restrictionType) {
+		if (!isValidRestrictionType(restrictionType)) return null;
+		return ImageProvider.get(buildImageName(restrictionType));
+	}
+ 	
+	/**
+	 * Builds the UI used to render turn restrictions 
+	 */
+	protected void build() {
+		setLayout(new GridBagLayout());
+		GridBagConstraints gc = new GridBagConstraints();
+		
+		// the turn restriction icon 		
+		gc.fill = GridBagConstraints.HORIZONTAL;
+		gc.weightx = 0.0;
+		gc.gridheight = 2;
+		gc.anchor = GridBagConstraints.CENTER;
+		gc.insets = new Insets(0,2,0,2);
+		add(icon = new JLabel(), gc);
+		
+		
+		// the name of the way with role "from"
+		gc.anchor = GridBagConstraints.NORTHWEST;
+		gc.gridx = 1;
+		gc.gridheight = 1;
+		gc.weightx = 0.0;
+		gc.insets = new Insets(0,0,0,0);
+		add(new JMultilineLabel("<html><strong>From:</strong></html>"), gc);
+		
+		gc.gridx = 2;
+		gc.weightx = 1.0; 
+		add(from = new JLabel(), gc);
+		
+		// the name of the way with role "to"
+		gc.anchor = GridBagConstraints.NORTHWEST;
+		gc.gridx = 1;
+		gc.gridy = 1;
+		gc.weightx = 0.0;
+		add(new JMultilineLabel("<html><strong>To:</strong></html>"), gc);
+		
+		gc.gridx = 2;
+		gc.weightx = 1.0;
+		add(to = new JLabel(), gc);
+	}
+
+	/**
+	 * Renders the icon for the turn restriction  
+	 * 
+	 * @param tr the turn restriction
+	 */
+	protected void renderIcon(Relation tr) {
+		String restrictionType = tr.get("restriction");
+		if (!isValidRestrictionType(restrictionType)) {
+			icon.setIcon(null);
+			return;
+		}
+		icon.setIcon(getIcon(restrictionType));
+	}
+
+	/**
+	 * Replies a way participating in this turn restriction in a given role
+	 * 
+	 * @param tr the turn restriction 
+	 * @param role the role (either "from" or "to")
+	 * @return the participating way; null, if no way is participating in this role
+	 */
+	private Way getParticipatingWay(Relation tr, String role){
+		for(RelationMember rm: tr.getMembers()){
+			if (rm.getRole().trim().toLowerCase().equals(role) && rm.getType().equals(OsmPrimitiveType.WAY)) {
+				return (Way)rm.getMember();
+			}
+		}
+		return null;
+	}
+	
+	protected void renderFrom(Relation tr) {
+		Way from = getParticipatingWay(tr, "from");
+		if (from == null) {
+			// FIXME: render as warning/error (red background?)
+			this.from.setText(tr("no participating way with role ''from''"));
+			return;
+		} 
+		this.from.setText(DefaultNameFormatter.getInstance().format(from));
+	}
+
+	protected void renderTo(Relation tr) {
+		Way to = getParticipatingWay(tr, "to");
+		if (to == null) {
+			// FIXME: render as warning/error (red background?)
+			this.to.setText(tr("no participating way with role ''to''"));
+			return;
+		} 
+		this.to.setText(DefaultNameFormatter.getInstance().format(to));
+	}
+
+	/**
+	 * Renders the foreground and background color depending on whether
+	 * the turn restriction is selected
+	 * 
+	 * @param isSelected true if the turn restriction is selected; false,
+	 * otherwise
+	 */
+	protected void renderColor(boolean isSelected) {
+		Color bg;
+		Color fg;
+		if (isSelected) {
+			bg = UIManager.getColor("List.selectionBackground");
+			fg = UIManager.getColor("List.selectionForeground");
+		} else {
+			bg = UIManager.getColor("background");
+			fg = UIManager.getColor("foreground");
+		}
+		setBackground(bg);
+		this.icon.setBackground(bg);
+		this.from.setBackground(bg);
+		this.to.setBackground(bg);
+		
+		setForeground(fg);
+		this.icon.setForeground(fg);
+		this.from.setForeground(fg);
+		this.to.setForeground(fg);
+	}
+		
+	public Component getListCellRendererComponent(JList list, Object value,
+			int index, boolean isSelected, boolean cellHasFocus) {
+
+		renderColor(isSelected);
+		Relation tr = (Relation)value;
+		renderIcon(tr);
+		renderFrom(tr);
+		renderTo(tr);		
+		return this;
+	}	
+}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsInDatasetListModel.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsInDatasetListModel.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsInDatasetListModel.java	(revision 20489)
@@ -0,0 +1,132 @@
+package org.openstreetmap.josm.plugins.turnrestrictions.list;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.logging.Logger;
+
+import javax.swing.DefaultListSelectionModel;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
+import org.openstreetmap.josm.data.osm.event.DataChangedEvent;
+import org.openstreetmap.josm.data.osm.event.DataSetListener;
+import org.openstreetmap.josm.data.osm.event.NodeMovedEvent;
+import org.openstreetmap.josm.data.osm.event.PrimitivesAddedEvent;
+import org.openstreetmap.josm.data.osm.event.PrimitivesRemovedEvent;
+import org.openstreetmap.josm.data.osm.event.RelationMembersChangedEvent;
+import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
+import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
+import org.openstreetmap.josm.gui.MapView.EditLayerChangeListener;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+
+/**
+ * This is the list model for the list of turn restrictions in the current data set.
+ * 
+ * The model is a {@see EditLayerChangeListener}. It initializes itself from the data set of
+ * the current edit layer.
+ * 
+ * The model is a {@see DataSetListener}. It updates itself to reflect the list of turn
+ * restrictions in the current data set. 
+ *
+ */
+public class TurnRestrictionsInDatasetListModel extends TurnRestrictionsListModel implements EditLayerChangeListener, DataSetListener {
+	private static final Logger logger = Logger.getLogger(TurnRestrictionsInDatasetListModel.class.getName());
+	
+	public TurnRestrictionsInDatasetListModel(
+			DefaultListSelectionModel selectionModel) {
+		super(selectionModel);
+	}
+	
+	/**
+	 * Filters the list of turn restrictions from a collection of OSM primitives.
+	 * 
+	 * @param primitives the primitives 
+	 * @return the list of turn restrictions 
+	 */
+	protected List<Relation> filterTurnRestrictions(Collection<? extends OsmPrimitive> primitives) {
+		List<Relation> ret = new LinkedList<Relation>();
+		if (primitives == null) return ret;
+		for(OsmPrimitive p: primitives){
+			if (!isTurnRestriction(p)) continue;
+			ret.add((Relation)p);
+		}
+		return ret;
+	}
+	
+	/* --------------------------------------------------------------------------- */
+	/* interface EditLayerChangeListener                                           */
+	/* --------------------------------------------------------------------------- */
+	public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) {
+		if (newLayer == null) {
+			setTurnRestrictions(null);
+			return;
+		}
+		List<Relation> turnRestrictions = new LinkedList<Relation>();
+		for (Relation r: newLayer.data.getRelations()) {
+			if (isValid(r) && isTurnRestriction(r)) {
+				turnRestrictions.add(r);
+			}
+		}
+		setTurnRestrictions(turnRestrictions);
+	}
+	
+	/* --------------------------------------------------------------------------- */
+	/* interface DataSetListener                                                   */
+	/* --------------------------------------------------------------------------- */	
+	public void dataChanged(DataChangedEvent event) {		
+		OsmDataLayer layer = Main.map.mapView.getEditLayer();
+		if (layer == null) {
+			setTurnRestrictions(null);
+		} else {
+			List<Relation> turnRestrictions = filterTurnRestrictions(layer.data.getRelations());
+			setTurnRestrictions(turnRestrictions);
+		}
+	}
+
+	public void primtivesAdded(PrimitivesAddedEvent event) {
+		List<Relation> turnRestrictions = filterTurnRestrictions(event.getPrimitives());
+		if (!turnRestrictions.isEmpty()) {
+			addTurnRestrictions(turnRestrictions);
+		}
+	}
+
+	public void primtivesRemoved(PrimitivesRemovedEvent event) {
+		List<Relation> turnRestrictions = filterTurnRestrictions(event.getPrimitives());
+		if (!turnRestrictions.isEmpty()) {
+			removeTurnRestrictions(turnRestrictions);
+		}
+	}
+
+	public void relationMembersChanged(RelationMembersChangedEvent event) {
+		List<Relation> turnRestrictions = filterTurnRestrictions(event.getPrimitives());
+		if (!turnRestrictions.isEmpty()) {
+			List<Relation> sel = getSelectedTurnRestrictions();
+			for(Relation tr: turnRestrictions) {	
+				// enforce a repaint of the respective turn restriction
+				int idx = getTurnRestrictionIndex(tr);
+				fireContentsChanged(this, idx,idx);
+			}
+			setSelectedTurnRestrictions(sel);
+		}
+	}
+
+	public void tagsChanged(TagsChangedEvent event) {
+		List<Relation> turnRestrictions = filterTurnRestrictions(event.getPrimitives());
+		if (!turnRestrictions.isEmpty()) {
+			List<Relation> sel = getSelectedTurnRestrictions();
+			for(Relation tr: turnRestrictions) {	
+				// enforce a repaint of the respective turn restriction
+				int idx = getTurnRestrictionIndex(tr);
+				fireContentsChanged(this, idx,idx);
+			}
+			setSelectedTurnRestrictions(sel);
+		}		
+	}
+
+	public void wayNodesChanged(WayNodesChangedEvent event) {/* ignore */}
+	public void nodeMoved(NodeMovedEvent event) {/* ignore */}
+	public void otherDatasetChange(AbstractDatasetChangedEvent event) {/* ignore */}
+}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsInDatasetView.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsInDatasetView.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsInDatasetView.java	(revision 20489)
@@ -0,0 +1,50 @@
+package org.openstreetmap.josm.plugins.turnrestrictions.list;
+
+import java.awt.BorderLayout;
+
+import javax.swing.DefaultListSelectionModel;
+import javax.swing.JList;
+import javax.swing.JScrollPane;
+import javax.swing.ListSelectionModel;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.event.DataSetListener;
+import org.openstreetmap.josm.data.osm.event.DatasetEventManager;
+import org.openstreetmap.josm.data.osm.event.DatasetEventManager.FireMode;
+import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.MapView.EditLayerChangeListener;
+
+/**
+ * This is the view for the list of turn restrictions in the current data set.
+ */
+public class TurnRestrictionsInDatasetView extends AbstractTurnRestrictionsListView{	
+	protected void build() {
+		DefaultListSelectionModel selectionModel = new DefaultListSelectionModel();
+		model = new TurnRestrictionsInDatasetListModel(selectionModel);
+		lstTurnRestrictions = new JList(model);
+		lstTurnRestrictions.setSelectionModel(selectionModel);
+		lstTurnRestrictions.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+		lstTurnRestrictions.setCellRenderer(new TurnRestrictionListCellRenderer());
+		
+		setLayout(new BorderLayout());
+		add(new JScrollPane(lstTurnRestrictions), BorderLayout.CENTER);
+	}
+
+	protected void registerAsListener() {
+		MapView.addEditLayerChangeListener((EditLayerChangeListener)model);
+		DatasetEventManager.getInstance().addDatasetListener((DataSetListener)model, FireMode.IN_EDT);
+		if (Main.main.getEditLayer() != null) {
+			model.setTurnRestrictions(Main.main.getEditLayer().data
+					.getRelations());
+		}
+	}
+
+	protected void unregisterAsListener() {
+		MapView.removeEditLayerChangeListener((EditLayerChangeListener)model);
+		DatasetEventManager.getInstance().removeDatasetListener((DataSetListener)model);
+	}
+
+	public TurnRestrictionsInDatasetView() {
+		build();
+	}
+}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsInSelectionListModel.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsInSelectionListModel.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsInSelectionListModel.java	(revision 20489)
@@ -0,0 +1,63 @@
+package org.openstreetmap.josm.plugins.turnrestrictions.list;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import javax.swing.DefaultListSelectionModel;
+
+import org.openstreetmap.josm.data.SelectionChangedListener;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.gui.MapView.EditLayerChangeListener;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+
+/**
+ * This is the list model for the list of turn restrictions related to OSM
+ * objects in the current selection.
+ */
+public class TurnRestrictionsInSelectionListModel extends TurnRestrictionsListModel implements EditLayerChangeListener, SelectionChangedListener {
+	private static final Logger logger = Logger.getLogger(TurnRestrictionsInSelectionListModel.class.getName());
+	
+	public TurnRestrictionsInSelectionListModel(
+			DefaultListSelectionModel selectionModel) {
+		super(selectionModel);
+	}
+	
+	/**
+	 * Initializes the model with the turn restrictions the primitives in 
+	 * {@code selection} participate.
+	 * 
+	 * @param selection the collection of selected primitives
+	 */
+	public void initFromSelection(Collection<? extends OsmPrimitive> selection) {
+		Set<Relation> turnRestrictions = new HashSet<Relation>();
+		if (selection == null) return;
+		for (OsmPrimitive p: selection) {
+			for (OsmPrimitive parent: p.getReferrers()) {
+				if (isTurnRestriction(parent))
+					turnRestrictions.add((Relation)parent);
+			}
+		}
+		setTurnRestrictions(turnRestrictions);
+	}
+
+	/* --------------------------------------------------------------------------- */
+	/* interface EditLayerChangeListener                                           */
+	/* --------------------------------------------------------------------------- */
+	public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) {
+		if (newLayer == null) {
+			setTurnRestrictions(null);
+			return;
+		}
+		initFromSelection(newLayer.data.getSelected());
+	}
+	
+	/* --------------------------------------------------------------------------- */
+	/* interface SelectionChangedListener                                          */
+	/* --------------------------------------------------------------------------- */	
+	public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
+		initFromSelection(newSelection);
+	}
+}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsInSelectionView.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsInSelectionView.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsInSelectionView.java	(revision 20489)
@@ -0,0 +1,52 @@
+package org.openstreetmap.josm.plugins.turnrestrictions.list;
+
+import java.awt.BorderLayout;
+
+import javax.swing.DefaultListSelectionModel;
+import javax.swing.JList;
+import javax.swing.JScrollPane;
+import javax.swing.ListSelectionModel;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.SelectionChangedListener;
+import org.openstreetmap.josm.data.osm.event.SelectionEventManager;
+import org.openstreetmap.josm.data.osm.event.DatasetEventManager.FireMode;
+import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.MapView.EditLayerChangeListener;
+
+/**
+ * This is the view for the list of turn restrictions related to objects in the 
+ * current selection.
+ * 
+ */
+public class TurnRestrictionsInSelectionView extends AbstractTurnRestrictionsListView {
+
+	protected void build() {
+		DefaultListSelectionModel selectionModel = new DefaultListSelectionModel();
+		model = new TurnRestrictionsInSelectionListModel(selectionModel);
+		lstTurnRestrictions = new JList(model);
+		lstTurnRestrictions.setSelectionModel(selectionModel);
+		lstTurnRestrictions.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+		lstTurnRestrictions.setCellRenderer(new TurnRestrictionListCellRenderer());
+		
+		setLayout(new BorderLayout());
+		add(new JScrollPane(lstTurnRestrictions), BorderLayout.CENTER);
+	}
+
+	protected void registerAsListener() {
+		MapView.addEditLayerChangeListener((EditLayerChangeListener)model);
+		SelectionEventManager.getInstance().addSelectionListener((SelectionChangedListener)model, FireMode.IN_EDT_CONSOLIDATED);
+		if (Main.main.getEditLayer() != null) {
+			model.setTurnRestrictions(Main.main.getEditLayer().data.getRelations());
+		}
+	}
+
+	protected void unregisterAsListener() {
+		MapView.removeEditLayerChangeListener((EditLayerChangeListener)model);
+		SelectionEventManager.getInstance().removeSelectionListener((SelectionChangedListener)model);
+	}
+
+	public TurnRestrictionsInSelectionView() {
+		build();
+	}
+}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsListDialog.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsListDialog.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsListDialog.java	(revision 20489)
@@ -0,0 +1,429 @@
+package org.openstreetmap.josm.plugins.turnrestrictions.list;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.MouseEvent;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+
+import javax.swing.AbstractAction;
+import javax.swing.JCheckBox;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.AutoScaleAction;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.SideButton;
+import org.openstreetmap.josm.gui.MapView.EditLayerChangeListener;
+import org.openstreetmap.josm.gui.dialogs.ToggleDialog;
+import org.openstreetmap.josm.gui.dialogs.relation.RelationEditor;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
+import org.openstreetmap.josm.plugins.turnrestrictions.editor.TurnRestrictionEditor;
+import org.openstreetmap.josm.plugins.turnrestrictions.editor.TurnRestrictionEditorManager;
+import org.openstreetmap.josm.tools.ImageProvider;
+
+/**
+ * This is the toggle dialog for turn restrictions. The user can switch between
+ * two lists of turn restrictions:
+ * <ol>
+ *   <li>the list of turn restrictions in the current data set</li>
+ *   <li>the list of turn restrictions related to OSM objects in the current selection</li>
+ * </ol>
+ * 
+ */
+public class TurnRestrictionsListDialog extends ToggleDialog{
+
+	/** checkbox for switching between the two list views */
+	private JCheckBox cbInSelectionOnly;
+	/** the view for the turn restrictions in the current data set */
+	private TurnRestrictionsInDatasetView pnlTurnRestrictionsInDataSet;
+	/** the view for the turn restrictions related to the current selection */
+	private TurnRestrictionsInSelectionView pnlTurnRestrictionsInSelection;
+	
+	/** three actions */
+	private NewAction actNew;
+	private EditAction actEdit;
+	private DeleteAction actDelete;	 
+	private SelectSelectedTurnRestrictions actSelectSelectedTurnRestrictions;
+	private ZoomToAction actZoomTo;
+	private SwitchListViewHandler switchListViewHandler;
+	
+	private AbstractTurnRestrictionsListView currentListView = null;
+	
+	/** the main content panel in this toggle dialog */
+	private JPanel pnlContent;
+	
+	@Override
+	public void showNotify() {
+		pnlTurnRestrictionsInDataSet.registerAsListener();		
+		pnlTurnRestrictionsInSelection.registerAsListener();
+		MapView.addEditLayerChangeListener(actNew);
+	}
+
+	@Override
+	public void hideNotify() {
+		pnlTurnRestrictionsInDataSet.unregisterAsListener();
+		pnlTurnRestrictionsInSelection.unregisterAsListener();
+		MapView.removeEditLayerChangeListener(actNew);
+	}
+
+	/**
+	 * Builds the panel with the checkbox for switching between the two
+	 * list views
+	 * 
+	 * @return the panel
+	 */
+	protected JPanel buildInSelectionOnlyTogglePanel(){
+		JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT,0,0));
+		pnl.setBorder(null);
+		pnl.add(cbInSelectionOnly = new JCheckBox(tr("Only participating in selection")));
+		cbInSelectionOnly.setToolTipText(tr(
+		   "<html>Select to display turn restrictions related to object in the current selection only.<br>"
+		 + "Deselect to display all turn restrictions in the current data set.</html>"));
+		return pnl;
+	}
+	
+	/**
+	 * Builds the panel with the action buttons 
+	 * 
+	 * @return the panel 
+	 */
+	protected JPanel buildCommandPanel() {
+		JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT,0,0));
+		pnl.setBorder(null);
+		pnl.add(new SideButton(actNew = new NewAction(), false /* don't show the name */));
+		pnl.add(new SideButton(actEdit = new EditAction(), false /* don't show the name */));
+		pnl.add(new SideButton(actDelete = new DeleteAction(), false /* don't show the name */));
+		
+		actSelectSelectedTurnRestrictions = new SelectSelectedTurnRestrictions();
+		actZoomTo = new ZoomToAction();
+		return pnl;
+	}
+	
+	/**
+	 * Builds the UI
+	 */
+	protected void build() {
+		pnlContent = new JPanel(new BorderLayout(0,0));
+		pnlContent.setBorder(null);
+		pnlContent.add(buildInSelectionOnlyTogglePanel(),  BorderLayout.NORTH);
+		pnlContent.add(buildCommandPanel(), BorderLayout.SOUTH);
+		
+		add(pnlContent, BorderLayout.CENTER);
+		
+		// create the two list views 
+		pnlTurnRestrictionsInDataSet = new TurnRestrictionsInDatasetView();
+		pnlTurnRestrictionsInSelection = new TurnRestrictionsInSelectionView();
+		
+		// wire the handler for switching between list views 
+		switchListViewHandler = new SwitchListViewHandler();
+		switchListViewHandler.activateListView(pnlTurnRestrictionsInDataSet);
+		cbInSelectionOnly.addItemListener(switchListViewHandler);
+		
+		// wire the popup menu launcher to the two turn restriction lists  
+		TurnRestrictionsPopupLauncher launcher = new TurnRestrictionsPopupLauncher();
+		pnlTurnRestrictionsInDataSet.getList().addMouseListener(launcher);
+		pnlTurnRestrictionsInSelection.getList().addMouseListener(launcher);
+	}
+	
+	/**
+	 * Constructor
+	 */
+	public TurnRestrictionsListDialog() {
+		super(
+				tr("Turn Restrictions"), 
+				"turnrestrictions",
+				tr("Display and manage turn restrictions in the current data set"),
+				null, // no shortcut
+				150   // default height
+		);
+		build();
+	}	
+	
+	/**
+	 * Switches between the two list view.
+	 */
+	class SwitchListViewHandler implements ItemListener {
+		public void activateListView(AbstractTurnRestrictionsListView view) {
+			if (currentListView != null) {
+				currentListView.removeListSelectionListener(actEdit);
+				currentListView.removeListSelectionListener(actDelete);
+				currentListView.removeListSelectionListener(actSelectSelectedTurnRestrictions);
+				currentListView.removeListSelectionListener(actZoomTo);
+				pnlContent.remove(currentListView);
+			}
+			pnlContent.add(view,BorderLayout.CENTER);
+			currentListView = view;						
+			view.addListSelectionListener(actEdit);
+			view.addListSelectionListener(actDelete);
+			view.addListSelectionListener(actSelectSelectedTurnRestrictions);
+			view.addListSelectionListener(actZoomTo);
+			actEdit.updateEnabledState();
+			actDelete.updateEnabledState();
+			actSelectSelectedTurnRestrictions.updateEnabledState();
+			actZoomTo.updateEnabledState();
+			currentListView.revalidate();
+			currentListView.repaint();
+		}
+
+		public void itemStateChanged(ItemEvent e) {
+			switch(e.getStateChange()) {
+			case ItemEvent.SELECTED:
+				activateListView(pnlTurnRestrictionsInSelection);
+				break;
+				
+			case ItemEvent.DESELECTED:		
+				activateListView(pnlTurnRestrictionsInDataSet);
+				break;
+			}
+		}
+	}
+	
+	 /**
+     * The edit action
+     *
+     */
+    class EditAction extends AbstractAction implements ListSelectionListener{
+        public EditAction() {
+            putValue(SHORT_DESCRIPTION,tr( "Open an editor for the selected turn restricion"));
+            putValue(SMALL_ICON, ImageProvider.get("dialogs", "edit"));
+            putValue(NAME, tr("Edit"));
+            setEnabled(false);
+        }
+        protected Collection<RelationMember> getMembersForCurrentSelection(Relation r) {
+            Collection<RelationMember> members = new HashSet<RelationMember>();
+            Collection<OsmPrimitive> selection = Main.map.mapView.getEditLayer().data.getSelected();
+            for (RelationMember member: r.getMembers()) {
+                if (selection.contains(member.getMember())) {
+                    members.add(member);
+                }
+            }
+            return members;
+        }
+
+		public void launchEditor(Relation toEdit) {
+			if (toEdit == null)
+				return;
+			OsmDataLayer layer = Main.main.getEditLayer();
+			TurnRestrictionEditorManager manager = TurnRestrictionEditorManager.getInstance();
+			TurnRestrictionEditor editor = manager.getEditorForRelation(layer, toEdit);
+			if (editor != null) {
+				editor.setVisible(true);
+				editor.toFront();
+			} else {
+				editor = new TurnRestrictionEditor(
+						TurnRestrictionsListDialog.this, layer,toEdit);
+				manager.positionOnScreen(editor);
+				manager.register(layer, toEdit,editor);
+				editor.setVisible(true);
+			}
+		}
+
+        public void actionPerformed(ActionEvent e) {
+            if (!isEnabled())
+                return;
+            List<Relation> toEdit = currentListView.getModel().getSelectedTurnRestrictions();
+            if (toEdit.size() != 1) return;
+            launchEditor(toEdit.get(0));
+        }
+
+        public void updateEnabledState() {
+        	setEnabled(currentListView!= null && currentListView.getModel().getSelectedTurnRestrictions().size() == 1);
+        }
+        
+        public void valueChanged(ListSelectionEvent e) {
+            updateEnabledState();
+        }
+    }
+
+    /**
+     * The delete action
+     *
+     */
+    class DeleteAction extends AbstractAction implements ListSelectionListener {
+        class AbortException extends Exception {}
+
+        public DeleteAction() {
+            putValue(SHORT_DESCRIPTION,tr("Delete the selected turn restriction"));
+            putValue(SMALL_ICON, ImageProvider.get("dialogs", "delete"));
+            putValue(NAME, tr("Delete"));
+            setEnabled(false);
+        }
+
+        protected void deleteRelation(Relation toDelete) {
+            if (toDelete == null)
+                return;
+            org.openstreetmap.josm.actions.mapmode.DeleteAction.deleteRelation(
+                    Main.main.getEditLayer(),
+                    toDelete
+            );
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            if (!isEnabled()) return;
+            List<Relation> toDelete = currentListView.getModel().getSelectedTurnRestrictions();
+            for (Relation r: toDelete) {
+                deleteRelation(r);
+            }
+        }
+        
+        public void updateEnabledState() {
+        	setEnabled(currentListView != null && !currentListView.getModel().getSelectedTurnRestrictions().isEmpty());
+        }
+
+        public void valueChanged(ListSelectionEvent e) {
+        	updateEnabledState();
+        }
+    }
+
+    /**
+     * The action for creating a new turn restriction
+     *
+     */
+     class NewAction extends AbstractAction implements EditLayerChangeListener{
+        public NewAction() {
+            putValue(SHORT_DESCRIPTION,tr("Create a new turn restriction"));
+            putValue(SMALL_ICON, ImageProvider.get("new"));
+            putValue(NAME, tr("New"));
+            updateEnabledState();
+        }
+
+        public void run() {
+        	 Relation tr = new Relation();
+        	 OsmDataLayer layer =  Main.main.getEditLayer();
+        	 if (layer == null) return;
+        	 TurnRestrictionEditor editor = new TurnRestrictionEditor(TurnRestrictionsListDialog.this, layer);
+             TurnRestrictionEditorManager.getInstance().positionOnScreen(editor);             
+             TurnRestrictionEditorManager.getInstance().register(layer, tr, editor);
+             editor.setVisible(true);
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            run();
+        }
+
+        protected void updateEnabledState() {
+            setEnabled(Main.main != null && Main.main.getEditLayer() != null);
+        }
+
+		public void editLayerChanged(OsmDataLayer oldLayer,
+				OsmDataLayer newLayer) {
+            updateEnabledState();
+		}
+    }
+    
+    /**
+     * Sets the selection of the current data set to the currently selected 
+     * turn restrictions.
+     *
+     */
+    class SelectSelectedTurnRestrictions extends AbstractAction implements ListSelectionListener {
+        class AbortException extends Exception {}
+
+        public SelectSelectedTurnRestrictions() {
+            putValue(SHORT_DESCRIPTION,tr("Set the current JOSM selection to the selected turn restrictions"));
+            putValue(SMALL_ICON, ImageProvider.get("selectall"));
+            putValue(NAME, tr("Select in current data layer"));
+            setEnabled(false);
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            if (!isEnabled()) return;
+            List<Relation> toSelect = currentListView.getModel().getSelectedTurnRestrictions();
+            if (toSelect.isEmpty()) return;
+            OsmDataLayer layer= Main.main.getEditLayer();
+            if (layer == null) return;
+            layer.data.setSelected(toSelect);
+        }
+        
+        public void updateEnabledState() {
+        	setEnabled(currentListView != null && !currentListView.getModel().getSelectedTurnRestrictions().isEmpty());
+        }
+
+        public void valueChanged(ListSelectionEvent e) {
+        	updateEnabledState();
+        }
+    }
+    
+    /**
+     * Sets the selection of the current data set to the currently selected 
+     * turn restrictions.
+     *
+     */
+    class ZoomToAction extends AbstractAction implements ListSelectionListener {
+        class AbortException extends Exception {}
+
+        public ZoomToAction() {
+            putValue(SHORT_DESCRIPTION,tr("Zoom to the currently selected turn restrictions"));
+            putValue(SMALL_ICON, ImageProvider.get("dialogs/autoscale/selection"));
+            putValue(NAME, tr("Zoom to"));
+            setEnabled(false);
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            if (!isEnabled()) return;
+            List<Relation> toSelect = currentListView.getModel().getSelectedTurnRestrictions();
+            if (toSelect.isEmpty()) return;
+            OsmDataLayer layer= Main.main.getEditLayer();
+            if (layer == null) return;
+            layer.data.setSelected(toSelect);
+            new AutoScaleAction("selection").autoScale();
+        }
+        
+        public void updateEnabledState() {
+        	setEnabled(currentListView != null && !currentListView.getModel().getSelectedTurnRestrictions().isEmpty());
+        }
+
+        public void valueChanged(ListSelectionEvent e) {
+        	updateEnabledState();
+        }
+    }
+    
+    /**
+     * The launcher for the popup menu.
+     * 
+     */
+    class TurnRestrictionsPopupLauncher extends PopupMenuLauncher {
+        @Override
+        public void launch(MouseEvent evt) {
+            JList lst = currentListView.getList();
+            if (lst.getSelectedIndices().length == 0) {
+                int idx = lst.locationToIndex(evt.getPoint());
+                if (idx >=0) {
+                    lst.getSelectionModel().addSelectionInterval(idx, idx);
+                }
+            }
+            TurnRestrictionsPopupMenu popup = new TurnRestrictionsPopupMenu();
+            popup.show(lst, evt.getX(), evt.getY());
+        }
+    }
+
+    /**
+     * The popup menu 
+     *
+     */
+    class TurnRestrictionsPopupMenu extends JPopupMenu {
+        public TurnRestrictionsPopupMenu() {
+            add(actNew);
+            add(actEdit);
+            add(actDelete);
+            addSeparator();
+            add(actSelectSelectedTurnRestrictions);
+            add(actZoomTo);
+        }
+    }
+}
Index: applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsListModel.java
===================================================================
--- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsListModel.java	(revision 20489)
+++ applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsListModel.java	(revision 20489)
@@ -0,0 +1,232 @@
+package org.openstreetmap.josm.plugins.turnrestrictions.list;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.swing.AbstractListModel;
+import javax.swing.DefaultListSelectionModel;
+
+import org.openstreetmap.josm.data.osm.NameFormatter;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.gui.DefaultNameFormatter;
+
+/**
+ * This is a list model for a list of turn restrictions.
+ * 
+ */
+public class TurnRestrictionsListModel extends AbstractListModel {
+    private final ArrayList<Relation> turnrestrictions = new ArrayList<Relation>();
+    private DefaultListSelectionModel selectionModel;
+
+    /**
+     * Creates the model
+     * 
+     * @param selectionModel the selection model used in the turn restriction list
+     */
+    public TurnRestrictionsListModel(DefaultListSelectionModel selectionModel) {
+        this.selectionModel = selectionModel;
+    }
+
+    /**
+     * Replies the turn restriction at position {@code idx} in the list.
+     * 
+     * @param idx the index 
+     * @return the turn restriction at position {@code idx} in the list.
+     */
+    public Relation getTurnRestriction(int idx) {
+        return turnrestrictions.get(idx);
+    }
+
+    /**
+     * Sorts the turn restrictions in this model 
+     */
+    public void sort() {
+        Collections.sort(
+                turnrestrictions,
+                new Comparator<Relation>() {
+                    NameFormatter formatter = DefaultNameFormatter.getInstance();
+
+                    public int compare(Relation r1, Relation r2) {
+                        return r1.getDisplayName(formatter).compareTo(r2.getDisplayName(formatter));
+                    }
+                }
+        );
+    }
+
+    protected boolean isValid(Relation r) {
+        return !r.isDeleted() && r.isVisible() && !r.isIncomplete();
+    }
+    
+    /**
+     * Replies true if the primitive {@code primitive} represents
+     * an OSM turn restriction.  
+     * 
+     * @param primitive the primitive 
+     * @return true if the primitive {@code primitive} represents
+     * an OSM turn restriction; false, otherwise
+     */
+    protected boolean isTurnRestriction(OsmPrimitive primitive) {
+    	if (primitive == null) return false;
+    	if (! (primitive instanceof Relation)) return false;
+    	String type = primitive.get("type");
+    	if (type == null || ! type.equals("restriction")) return false;
+    	return true;
+    }
+    
+    /**
+     * Populates the model with the turn restrictions in {@code turnrestrictions}.
+     * 
+     * @param turnrestrictions the turn restrictions 
+     */
+    public void setTurnRestrictions(Collection<Relation> turnrestrictions) {
+        List<Relation> sel =  getSelectedTurnRestrictions();
+        this.turnrestrictions.clear();
+        if (turnrestrictions == null) {
+            selectionModel.clearSelection();
+            fireContentsChanged(this,0,getSize());
+            return;
+        }
+        for (Relation r: turnrestrictions) {
+            if (isValid(r) && isTurnRestriction(r)) {
+                this.turnrestrictions.add(r);
+            }
+        }
+        sort();
+        fireIntervalAdded(this, 0, getSize());
+        setSelectedTurnRestrictions(sel);
+    }
+
+    /**
+     * Add all turn restrictions in <code>addedPrimitives</code> to the model for the
+     * relation list dialog
+     *
+     * @param addedPrimitives the collection of added primitives. May include nodes,
+     * ways, and relations.
+     */
+    public void addTurnRestrictions(Collection<? extends OsmPrimitive> addedPrimitives) {
+        boolean added = false;
+        for (OsmPrimitive p: addedPrimitives) {
+            if (! isTurnRestriction(p)) {
+                continue;
+            }
+
+            Relation r = (Relation)p;
+            if (!isValid(r)) continue;
+            if (turnrestrictions.contains(r)) {
+                continue;
+            }
+			turnrestrictions.add(r);
+			added = true;
+        }
+        if (added) {
+            List<Relation> sel = getSelectedTurnRestrictions();
+            sort();
+            fireIntervalAdded(this, 0, getSize());
+            setSelectedTurnRestrictions(sel);
+        }
+    }
+
+    /**
+     * Removes all turn restrictions in <code>removedPrimitives</code> from the model
+     *
+     * @param removedPrimitives the removed primitives. May include nodes, ways,
+     *   and relations
+     */
+    public void removeTurnRestrictions(Collection<? extends OsmPrimitive> removedPrimitives) {
+        if (removedPrimitives == null) return;
+        Set<Relation> removedTurnRestrictions = new HashSet<Relation>();
+        for (OsmPrimitive p: removedPrimitives) {
+        	if (!isTurnRestriction(p)) continue;
+            removedTurnRestrictions.add((Relation)p);
+        }
+        if (removedTurnRestrictions.isEmpty())return;
+        int size = turnrestrictions.size();
+        turnrestrictions.removeAll(removedTurnRestrictions);
+        if (size != turnrestrictions.size()) {
+            List<Relation> sel = getSelectedTurnRestrictions();
+            sort();
+            fireContentsChanged(this, 0, getSize());
+            setSelectedTurnRestrictions(sel);
+        }
+    }
+
+    public Object getElementAt(int index) {
+        return turnrestrictions.get(index);
+    }
+
+    public int getSize() {
+        return turnrestrictions.size();
+    }
+
+    /**
+     * Replies the list of selected, non-new relations. Empty list,
+     * if there are no selected, non-new relations.
+     *
+     * @return the list of selected, non-new relations.
+     */
+    public List<Relation> getSelectedNonNewRelations() {
+        ArrayList<Relation> ret = new ArrayList<Relation>();
+        for (int i=0; i<getSize();i++) {
+            if (!selectionModel.isSelectedIndex(i)) {
+                continue;
+            }
+            if (turnrestrictions.get(i).isNew()) {
+                continue;
+            }
+            ret.add(turnrestrictions.get(i));
+        }
+        return ret;
+    }
+
+    /**
+     * Replies the list of selected turn restrictions. Empty list,
+     * if there are no selected turn restrictions.
+     *
+     * @return the list of selected turn restrictions
+     */
+    public List<Relation> getSelectedTurnRestrictions() {
+        ArrayList<Relation> ret = new ArrayList<Relation>();
+        for (int i=0; i<getSize();i++) {
+            if (!selectionModel.isSelectedIndex(i)) {
+                continue;
+            }
+            ret.add(turnrestrictions.get(i));
+        }
+        return ret;
+    }
+
+    /**
+     * Sets the selected turn restrictions
+     *
+     * @return sel the list of selected turn restrictions
+     */
+    public void setSelectedTurnRestrictions(List<Relation> sel) {
+        selectionModel.clearSelection();
+        if (sel == null || sel.isEmpty())
+            return;
+        for (Relation r: sel) {
+            int i = turnrestrictions.indexOf(r);
+            if (i<0) {
+                continue;
+            }
+            selectionModel.addSelectionInterval(i,i);
+        }
+    }
+
+    /**
+     * Returns the index of a turn restriction 
+     *
+     * @return index of relation (-1, if not found)
+     */
+    public int getTurnRestrictionIndex(Relation tr) {
+        int i = turnrestrictions.indexOf(tr);
+        if (i<0)return -1;
+        return i;
+    }
+}
