Index: /applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionBuilder.java
===================================================================
--- /applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionBuilder.java	(revision 23592)
+++ /applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionBuilder.java	(revision 23593)
@@ -1,3 +1,7 @@
 package org.openstreetmap.josm.plugins.turnrestrictions;
+
+import static org.openstreetmap.josm.plugins.turnrestrictions.TurnRestrictionBuilder.determineWayJoinOrientation;
+import static org.openstreetmap.josm.plugins.turnrestrictions.TurnRestrictionBuilder.isEndNode;
+import static org.openstreetmap.josm.plugins.turnrestrictions.TurnRestrictionBuilder.isStartNode;
 
 import java.util.ArrayList;
@@ -5,4 +9,5 @@
 import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.openstreetmap.josm.data.osm.Node;
@@ -12,4 +17,5 @@
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.plugins.turnrestrictions.editor.TurnRestrictionLegRole;
 import org.openstreetmap.josm.plugins.turnrestrictions.editor.TurnRestrictionType;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
@@ -22,4 +28,260 @@
  */
 public class TurnRestrictionBuilder {
+	
+	/**
+	 * Replies the angle phi in the polar coordinates (r,phi) representing the first
+	 * segment of the way {@code w}, where w is moved such that the start node of {@code w} is
+	 * in the origin (0,0).
+	 *  
+	 * @param w the way.  Must not be null. At least two nodes required. 
+	 * @return phi in the polar coordinates 
+	 * @throws IllegalArgumentException thrown if w is null
+	 * @throws IllegalArgumentException thrown if w is too short (at least two nodes required)
+	 */
+    static public double phi(Way w) throws IllegalArgumentException{
+    	return phi(w, false /* not inverse */);
+    }
+    
+    /**
+     * <p>Replies the angle phi in the polar coordinates (r,phi) representing the first
+	 * segment of the way {@code w}, where w is moved such that the start node of {@code w} is
+	 * in the origin (0,0).</p>
+	 * 
+	 * <p>If {@code doInvert} is true, computes phi for the way in reversed direction.</p>
+	 * 
+	 * @param w the way.  Must not be null. At least two nodes required.
+	 * @param doInvert if true, computes phi for the reversed way 
+	 * @return phi in the polar coordinates 
+	 * @throws IllegalArgumentException thrown if w is null
+	 * @throws IllegalArgumentException thrown if w is too short (at least two nodes required)
+     */
+    static public double phi(Way w, boolean doInvert) throws IllegalArgumentException {
+    	CheckParameterUtil.ensureParameterNotNull(w, "w");
+    	if (w.getNodesCount() < 2) {
+    		throw new IllegalArgumentException("can't compute phi for way with less than 2 nodes");
+    	}
+    	List<Node> nodes = w.getNodes();
+    	if (doInvert) Collections.reverse(nodes);
+    	Node n0 = nodes.get(0);
+    	Node n1 = nodes.get(1);
+    	
+    	double x = n1.getCoor().getX() - n0.getCoor().getX();
+    	double y = n1.getCoor().getY() - n0.getCoor().getY();
+    	return Math.atan2(y, x);  	
+    }    
+
+    /**
+     * Replies the unique common node of two ways, or null, if either no
+     * such node or multiple common nodes exist.
+     * 
+     * @param w1 the first way
+     * @param w2 the second way
+     * @return the common node or null, if w1 is null, or if w2 is null or if
+     * w1 and w2 don't share exactly one node
+     */
+    static public Node getUniqueCommonNode(Way w1, Way w2) throws IllegalArgumentException{
+    	Set<Node> w1Nodes = new HashSet<Node>(w1.getNodes());
+    	w1Nodes.retainAll(w2.getNodes());
+    	if (w1Nodes.size() != 1) return null;
+    	return w1Nodes.iterator().next();
+    }   
+        
+    /**
+     * Replies true, if {@code n} is the start node of the way {@code w}.
+     * 
+     * @param w the way. Must not be null.
+     * @param n the node. Must not be null.
+     * @return true, if {@code n} is the start node of the way {@code w}.
+     */
+    static public boolean isStartNode(Way w, Node n) {
+    	if (w.getNodesCount() == 0) return false;
+    	return w.getNode(0).equals(n);
+    }
+        
+    /**
+     * Replies true, if {@code n} is the end node of the way {@code w}.
+     * 
+     * @param w the way. Must not be null.
+     * @param n the node. Must not be null.
+     * @return true, if {@code n} is the end node of the way {@code w}.
+     */
+    static public boolean isEndNode(Way w, Node n){
+    	if (w.getNodesCount() == 0) return false;
+    	return w.getNode(w.getNodesCount()-1).equals(n);
+    }
+    
+    /**
+     * Replies true, if {@code n} is a node in the way {@code w} but {@code n}
+     * is neither the start nor the end node.
+     * 
+     * @param w the way 
+     * @param n the node 
+     * @return true if {@code n} is an "inner" node
+     */
+    static public boolean isInnerNode(Way w, Node n){
+    	if (!w.getNodes().contains(n)) return false;
+    	if (isStartNode(w, n)) return false;
+    	if (isEndNode(w, n)) return false;
+    	return true;     	
+    }
+    
+    /**
+     * <p>Replies the angle at which way {@code from} and {@code to} are connected
+     * at exactly one common node.</p> 
+     * 
+     * <p>If the result is positive, the way {@code from} bends to the right, if it
+     * is negative, the {@code to} bends to the left.</p>
+     * 
+     * <p>The two ways must not be null and they must be connected at exactly one 
+     * common node. They must <strong>not intersect</code> at this node.</p>.
+     * 
+     * @param from the from way
+     * @param to the to way
+     * @return the intersection angle 
+     * @throws IllegalArgumentException thrown if the two nodes don't have exactly one common
+     * node at which they are connected
+     * 
+     */
+    static public double interesectionAngle(Way from, Way to) throws IllegalArgumentException {
+	    Node via = getUniqueCommonNode(from, to);
+	    if (via == null) 
+	    	throw new IllegalArgumentException("the two ways must share exactly one common node"); // no I18n required
+	    if (!isStartNode(from, via) && ! isEndNode(from, via)) 
+	    	throw new IllegalArgumentException("via node must be start or end node of from-way"); // no I18n required
+	    if (!isStartNode(to, via) && ! isEndNode(to, via)) 
+	    	throw new IllegalArgumentException("via node must be start or end node of to-way"); // no I18n required
+	    double phi1 = phi(from, isStartNode(from, via));
+	    double phi2 = phi(to, isEndNode(to, via));		
+		return phi1 - phi2;
+    }   
+        
+    static public enum RelativeWayJoinOrientation {
+    	LEFT,
+    	RIGHT
+    }
+    /**
+     * <p>Determines the orientation in which two ways {@code from} and {@code to}
+     * are connected, with respect to the direction of the way {@code from}.</p> 
+     * 
+     * <p>The following preconditions must be met:
+     *   <ul>
+     *     <li>{@code from} and {@code to} must not be null</li>
+     *     <li>they must have exactly one common node <em>n</em> </li>
+     *     <li><em>n</em> must occur exactly once in {@code from} and {@code to}, i.e. the
+     *     two ways must not be closed at <em>n</em></li>
+     *     <li><em>n</em> must be the start or the end node of both ways </li>
+     *   </ul>
+     * </p>
+     * 
+     * <p>Here's a typical configuration:</p>
+     * <pre>
+     *          to1             to2
+     *      -------------> o -------------->
+     *                     ^
+     *                     | from
+     *                     |
+     * </pre>
+     * 
+     * <p>Replies null, if the preconditions aren't met and the method fails to
+     *  determine the join orientation.</p>
+     * 
+     * @param from the "from"-way
+     * @param to the "to"-way
+     * @return the join orientation or null, if the method fails to compute the
+     * join orientation
+     */
+    public static RelativeWayJoinOrientation determineWayJoinOrientation(Way from, Way to){
+    	Node via = getUniqueCommonNode(from, to);
+    	if (via == null) return null;
+    	if (!isConnectingNode(from, to, via)) return null;
+    	// if either w1 or w2 are closed at the via node, we can't determine automatically
+    	// whether the connection at "via" is a "left turn" or a "right turn"
+    	if (isClosedAt(from, via)) return null;
+    	if (isClosedAt(to, via)) return null;
+    	
+    	double phi = interesectionAngle(from, to);    	
+    	if (phi >=0 && phi <= Math.PI) {
+    		return RelativeWayJoinOrientation.RIGHT;
+    	} else {
+    		return RelativeWayJoinOrientation.LEFT;
+    	} 
+    }
+    
+    /**
+     * <p>Selects either of the two ways resulting from the split of a way
+     * in the role {@link TurnRestrictionLegRole#TO TO}.</p>
+     * 
+     * <p>This methods operates on three ways for which the following
+     * preconditions must be met:
+     * <ul>
+     *   <li>{@code t1} and {@code t2} are connected at a common node <em>n</em></li>
+     *   <li>{@code from} is also connected to the node <em>n</em>. <em>n</em> occurs
+     *   exactly once in {@code from} and is either the start or the end node of {@code from}.</li>
+     * </ul>
+     * </p>
+     * 
+     * <p>Here's a typical configuration:</p>
+     * <pre>
+     *          to1             to2
+     *      -------------> o -------------->
+     *                     ^
+     *                     | from
+     *                     |
+     * </pre>
+     * 
+     * <p>Depending on {@code restrictionType}, this method either returns {@code to1}
+     * or {@code to2}. If {@code restrictionType} indicates that our context is a 
+     * "left turn", {@code to1} is replied. If our context is a "right turn", {@code to2}
+     * is returned.</p>
+     * 
+     * <p>Replies null, if the expected preconditions aren't met or if we can't infer
+     * from {@code restrictionType} whether our context is a "left turn" or a "right turn".</p>
+     * 
+     * @param from the from-way
+     * @param to1 the first part of the split to-way
+     * @param to2 the second part of the split to-way
+     * @param restrictionType the restriction type
+     * @return either {@code to1}, {@code to2}, or {@code null}.
+     */
+    static public Way selectToWayAfterSplit(Way from, Way to1, Way to2, TurnRestrictionType restrictionType){
+    	if (restrictionType == null) return null;
+    	Node cn1 = TurnRestrictionBuilder.getUniqueCommonNode(from, to1);
+    	if (cn1 == null) return null;
+    	Node cn2 = TurnRestrictionBuilder.getUniqueCommonNode(from, to2);
+    	if (cn2 == null) return null;
+    	if (cn1 != cn2) return null;        	
+    	
+    	if (! isStartNode(from, cn1) && ! isEndNode(from, cn1)) {
+    		/*
+    		 * the now split to-way still *interesects* the from-way. We
+    		 * can't adjust the split decisions. 
+    		 */
+    		return null;
+    	}
+    	
+    	RelativeWayJoinOrientation o1 = determineWayJoinOrientation(from, to1);
+    	RelativeWayJoinOrientation o2 = determineWayJoinOrientation(from, to2);
+    	
+        switch(restrictionType){
+        case NO_LEFT_TURN:
+        case ONLY_LEFT_TURN:
+        	if (RelativeWayJoinOrientation.LEFT.equals(o1)) return to1;
+        	else if (RelativeWayJoinOrientation.LEFT.equals(o2)) return to2;
+        	else return null;
+        	
+        case NO_RIGHT_TURN:
+        case ONLY_RIGHT_TURN:
+        	if (RelativeWayJoinOrientation.RIGHT.equals(o1)) return to1;
+        	else if (RelativeWayJoinOrientation.RIGHT.equals(o2)) return to2;
+        	else return null;
+        	
+        default:
+	       	 /*
+	       	  * For restriction types like NO_U_TURN, NO_STRAIGHT_ON, etc. we
+	       	  * can select a "left" or "right" way after splitting.
+	       	  */
+        	return null;
+        }
+    }
     
     public TurnRestrictionBuilder(){
@@ -74,44 +336,4 @@
 
     /**
-     * Replies the unique common node of two ways, or null, if either no
-     * such node or multiple common nodes exist.
-     * 
-     * @param w1 the first way
-     * @param w2 the second way
-     * @return the common node
-     */
-    protected Node getUniqueCommonNode(Way w1, Way w2){
-    	List<Node> w1Nodes = w1.getNodes();
-    	w1Nodes.retainAll(w2.getNodes());
-    	if (w1Nodes.size() != 1) return null;
-    	return w1Nodes.get(0);
-    }    
-    
-    /**
-     * Replies true, if {@code n} is the start node of the way {@code w}.
-     * 
-     * @param w the way 
-     * @param n the node 
-     * @return true, if {@code n} is the start node of the way {@code w}.
-     */
-    protected boolean isStartNode(Way w, Node n) {
-    	if (w.getNodesCount() == 0) return false;
-    	return w.getNode(0).equals(n);
-    }
-    
-    
-    /**
-     * Replies true, if {@code n} is the end node of the way {@code w}.
-     * 
-     * @param w the way 
-     * @param n the node 
-     * @return true, if {@code n} is the end node of the way {@code w}.
-     */
-    protected boolean isEndNode(Way w, Node n){
-    	if (w.getNodesCount() == 0) return false;
-    	return w.getNode(w.getNodesCount()-1).equals(n);
-    }
-    
-    /**
      * <p>Replies true, if the ways {@code w1} and {@code w2} are connected
      * at the node {@code n}.</p>
@@ -125,5 +347,5 @@
      * @return
      */
-    protected boolean isConnectingNode(Way w1, Way w2, Node n){
+    public static boolean isConnectingNode(Way w1, Way w2, Node n){
     	if (isStartNode(w1, n)) {
     		return isStartNode(w2, n)  | isEndNode(w2, n);
@@ -141,91 +363,10 @@
      * @return true, if the way {@code w} is closed at the node {@code n}.
      */
-    protected boolean isClosedAt(Way w, Node n){
+    public static boolean isClosedAt(Way w, Node n){
     	List<Node> nodes = w.getNodes();
     	nodes.retainAll(Collections.singletonList(n));
     	return nodes.size() >= 2;
     }
-    
-    protected double phi(Way w) {
-    	return phi(w, false /* not inverse */);
-    }
-    
-    protected double phi(Way w, boolean doInvert) {
-    	double x1 = w.getNode(0).getCoor().getX();
-    	double y1 = w.getNode(0).getCoor().getY();
-    	double x2 = w.getNode(w.getNodesCount()-1).getCoor().getX();
-    	double y2 = w.getNode(w.getNodesCount()-1).getCoor().getY();
-    	if (doInvert){
-    		double t = x1; x1 = x2; x2 = t;
-    		t = y1; y1 = y2; y2 = t;
-    	}
-    	x2-=x1;
-    	y2-=y1;
-    	return phi(x2,y2);    	
-    }
-    
-    protected double phi(double x, double y) {
-    	return Math.atan2(y, x);
-    }   
-    
-    /**
-     * <p>Determines the standard turn restriction between from way {@code w1} to
-     * way {@code w2}.</p>
-     * 
-     * <p>Replies {@link TurnRestrictionType#NO_LEFT_TURN no_left_turn} or 
-     * {@link TurnRestrictionType#NO_RIGHT_TURN no_right_turn}, if applicable. Or
-     * null, if neither of these restrictions is applicable, for instance because
-     * the passed in via node {@code via} isn't a node where the two ways are
-     * connected.</p>
-     * 
-     * @param w1 the "from"-way
-     * @param w2 the "to"-way
-     * @param via the via node
-     * @return an applicable turn restriction, or null, if no turn restriction is
-     * applicable
-     */
-    protected String determineRestriction(Way w1, Way w2, Node via){
-    	if (via == null) return null;
-    	if (!isConnectingNode(w1, w2, via)) return null;
-    	// if either w1 or w2 are closed at the via node, we can't determine automatically
-    	// whether the connection at "via" is a "left turn" or a "right turn"
-    	if (isClosedAt(w1, via)) return null;
-    	if (isClosedAt(w2, via)) return null;
-    	
-    	double phi1 = 0, phi2 = 0;
-    	if (isEndNode(w1, via)){
-    		if (isStartNode(w2, via)) {
-	    		phi1 = phi(w1);
-	    		phi2 = phi(w2);
-    		} else if (isEndNode(w2, via)){
-    			phi1 = phi(w1);
-    			phi2 = phi(w2, true /* reverse it */);
-    		} else {
-    			assert false: "Unexpected state: via node is expected to be a start or and end node";
-    		}	    		
-    	} else if (isStartNode(w1,via)) {
-    		if (isStartNode(w2, via)) {
-	    		phi1 = phi(w1, true /* reverse it */);
-	    		phi2 = phi(w2);
-    		} else if (isEndNode(w2, via)){
-    			phi1 = phi(w1, true /* reverse it */);
-    			phi2 = phi(w2, true /* reverse it */);
-    		} else {
-    			assert false: "Unexpected state: via node is expected to be a start or and end node";
-    		}	    
-    	} else {
-    		assert false: "Unexpected state: via node is expected to be a start or and end node of w1";    		
-    	}
-    	
-    	double phi = phi1-phi2;
-    	if (phi >=0 && phi <= Math.PI) {
-    		// looks like a right turn  
-    		return TurnRestrictionType.NO_RIGHT_TURN.getTagValue();
-    	} else {
-    		// looks like a left turn 
-    		return TurnRestrictionType.NO_LEFT_TURN.getTagValue();
-    	} 
-    }
-    
+   
     protected Relation initTurnRestrictionFromTwoWays(List<OsmPrimitive> primitives) {
     	Way w1 = null;
@@ -273,7 +414,14 @@
     	if (via != null){
     		tr.addMember(new RelationMember("via", via));
-    		String restriction = determineRestriction(w1, w2, via); 
-    		if (restriction != null){
-    			tr.put("restriction", restriction);
+    		RelativeWayJoinOrientation orientation = determineWayJoinOrientation(w1, w2);
+    		if (orientation != null){
+    			switch(orientation){
+    			case LEFT:
+    				tr.put("restriction", TurnRestrictionType.NO_LEFT_TURN.getTagValue());
+    				break;
+    			case RIGHT:
+    				tr.put("restriction", TurnRestrictionType.NO_RIGHT_TURN.getTagValue());
+    				break;    				
+    			}
     		}
     	}
Index: /applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/IdenticalTurnRestrictionLegsError.java
===================================================================
--- /applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/IdenticalTurnRestrictionLegsError.java	(revision 23592)
+++ /applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/IdenticalTurnRestrictionLegsError.java	(revision 23593)
@@ -27,5 +27,5 @@
     @Override
     public String getText() {       
-        return tr("This turn restriction uses the OSM way <span class=\"object-name\">{0}</span> with role <tt>from</tt> <strong>and</strong> with role <tt>to</tt>. "
+        return tr("This turn restriction uses the way <span class=\"object-name\">{0}</span> with role <tt>from</tt> <strong>and</strong> with role <tt>to</tt>. "
                 + "In a turn restriction, the way with role <tt>from</tt> should be different from the way with role <tt>to</tt>, though.",
                 leg.getDisplayName(DefaultNameFormatter.getInstance())
Index: /applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/IssuesModel.java
===================================================================
--- /applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/IssuesModel.java	(revision 23592)
+++ /applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/IssuesModel.java	(revision 23593)
@@ -1,7 +1,8 @@
 package org.openstreetmap.josm.plugins.turnrestrictions.qa;
+
+import static org.openstreetmap.josm.plugins.turnrestrictions.TurnRestrictionBuilder.isInnerNode;
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Observable;
@@ -14,4 +15,5 @@
 import org.openstreetmap.josm.gui.tagging.TagEditorModel;
 import org.openstreetmap.josm.gui.tagging.TagModel;
+import org.openstreetmap.josm.plugins.turnrestrictions.TurnRestrictionBuilder;
 import org.openstreetmap.josm.plugins.turnrestrictions.editor.ExceptValueModel;
 import org.openstreetmap.josm.plugins.turnrestrictions.editor.NavigationControler;
@@ -190,14 +192,4 @@
     }
     
-    protected Node getNodeAtIntersection(Way from, Way to){
-        Set<Node> fromNodes = new HashSet<Node>(from.getNodes());
-        fromNodes.retainAll(to.getNodes());
-        if (fromNodes.size() == 1){
-            return fromNodes.iterator().next();
-        } else {
-            return null;
-        }
-    }
-    
     /**
      * Checks the 'via' members in the turn restriction
@@ -215,17 +207,16 @@
         Way from = (Way)fromLegs.iterator().next();
         Way to = (Way)toLegs.iterator().next();
-        Node intersect = getNodeAtIntersection(from, to);
+        Node intersect = TurnRestrictionBuilder.getUniqueCommonNode(from, to);        
         if (intersect != null){
             if (!editorModel.getVias().contains(intersect)) {
                 issues.add(new IntersectionMissingAsViaError(this, from, to, intersect));
             }
-            // 'from' intersects with 'to' - should be split  
-            if (from.getNode(0) != intersect && from.getNode(from.getNodesCount()-1) != intersect){
-                issues.add(new TurnRestrictionLegSplitRequiredError(this, TurnRestrictionLegRole.FROM, from, to, intersect));
-            }
-            // 'to' intersects with 'from' - should be split
-            if (to.getNode(0) != intersect && to.getNode(to.getNodesCount()-1) != intersect){
-                issues.add(new TurnRestrictionLegSplitRequiredError(this, TurnRestrictionLegRole.TO, from, to, intersect));
-            }                  
+        	if (isInnerNode(from, intersect) && isInnerNode(to, intersect)) {
+        		issues.add(new TurnRestrictionLegSplitRequiredError(this, from, to));
+        	} else if (isInnerNode(from, intersect) && ! isInnerNode(to, intersect)) {
+        		issues.add(new TurnRestrictionLegSplitRequiredError(this, TurnRestrictionLegRole.FROM, from, to, intersect));
+        	} else if (!isInnerNode(from, intersect) && isInnerNode(to, intersect)) {
+        		issues.add(new TurnRestrictionLegSplitRequiredError(this, TurnRestrictionLegRole.TO, from, to, intersect));
+        	}
         } else {
         	if (editorModel.getVias().isEmpty() && ! from.equals(to)){
Index: /applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/MissingTurnRestrictionLegError.java
===================================================================
--- /applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/MissingTurnRestrictionLegError.java	(revision 23592)
+++ /applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/MissingTurnRestrictionLegError.java	(revision 23593)
@@ -34,11 +34,11 @@
         switch(role){
         case FROM: 
-            msg = tr("An OSM way with role <tt>from</tt> is required in a turn restriction.");
+            msg = tr("A way with role <tt>from</tt> is required in a turn restriction.");
             break;
         case TO: 
-            msg = tr("An OSM way with role <tt>to</tt> is required in a turn restriction.");
+            msg = tr("A way with role <tt>to</tt> is required in a turn restriction.");
             break;
         }
-        msg += " " + tr("Please go to the Basic editor and manually choose an OSM way.");
+        msg += " " + tr("Please go to the Basic editor and manually choose a way.");
         return msg;
     }
@@ -49,8 +49,8 @@
             switch(role){
             case FROM:
-                putValue(SHORT_DESCRIPTION, tr("Add an OSM way with role ''from''"));
+                putValue(SHORT_DESCRIPTION, tr("Add a way with role ''from''"));
                 break;
             case TO:
-                putValue(SHORT_DESCRIPTION, tr("Add an OSM way with role ''to''"));
+                putValue(SHORT_DESCRIPTION, tr("Add a way with role ''to''"));
                 break;              
             }           
Index: /applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/TurnRestrictionLegSplitRequiredError.java
===================================================================
--- /applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/TurnRestrictionLegSplitRequiredError.java	(revision 23592)
+++ /applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/TurnRestrictionLegSplitRequiredError.java	(revision 23593)
@@ -4,5 +4,7 @@
 
 import java.awt.event.ActionEvent;
+import java.util.Arrays;
 import java.util.Collections;
+import java.util.logging.Logger;
 
 import javax.swing.AbstractAction;
@@ -15,5 +17,8 @@
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.gui.DefaultNameFormatter;
+import org.openstreetmap.josm.plugins.turnrestrictions.TurnRestrictionBuilder;
 import org.openstreetmap.josm.plugins.turnrestrictions.editor.TurnRestrictionLegRole;
+import org.openstreetmap.josm.plugins.turnrestrictions.editor.TurnRestrictionType;
+import org.openstreetmap.josm.tools.CheckParameterUtil;
 
 /**
@@ -23,8 +28,34 @@
  */
 public class TurnRestrictionLegSplitRequiredError extends Issue{
+	static private final Logger logger = Logger.getLogger(TurnRestrictionLegSplitRequiredError.class.getName());
+	
     private TurnRestrictionLegRole role;
     private Way from;
     private Way to;
-    private Node interesect;
+    private Node intersect;
+    
+    /**
+     * <p>Creates the issue for a pair of ways {@code from} and {@code to} which interesect
+     * at node {@code intersect}.</p>
+     * 
+     * @param parent the parent model 
+     * @param from the way with role "from"
+     * @param to the way with role "to"
+     * @param intersect the intersection node 
+     */
+    public TurnRestrictionLegSplitRequiredError(IssuesModel parent, Way from, Way to){
+    	super(parent, Severity.ERROR);
+    	CheckParameterUtil.ensureParameterNotNull(from, "from");
+    	CheckParameterUtil.ensureParameterNotNull(to, "to"); 
+    	
+    	intersect= TurnRestrictionBuilder.getUniqueCommonNode(from, to);
+    	if (intersect == null)
+    		throw new IllegalArgumentException("exactly one intersecting node required");
+    	
+    	this.from = from;
+    	this.to = to;
+    	this.role = null;
+    	actions.add(new SplitAction());
+    }
 
     /**
@@ -35,5 +66,5 @@
      * @param from the way with role 'from'
      * @param to the way with role 'to'
-     * @param interesect the node at the intersection
+     * @param intersect the node at the intersection
      */
     public TurnRestrictionLegSplitRequiredError(IssuesModel parent, TurnRestrictionLegRole role, Way from, Way to, Node intersect) {
@@ -42,5 +73,5 @@
         this.from = from;
         this.to = to;
-        this.interesect = intersect;
+        this.intersect = intersect;
         actions.add(new SplitAction());
     }
@@ -49,20 +80,40 @@
     public String getText() {
         String msg = null;
+        if (role == null){
+        	/*
+        	 * from and to intersect at a common node. Both have to be split.
+        	 */
+        	return tr("The way <span class=\"object-name\">{0}</span> with role <tt>from</tt> and the "
+        			+ "way <span class=\"object-name\">{1}</span> with role <tt>to</tt> intersect "        			
+        			+ "at node <span class=\"object-name\">{2}</span>. "
+        			+ "<p> "
+        			+ "Both ways should be split at the intersecting node.",
+                    from.getDisplayName(DefaultNameFormatter.getInstance()),
+                    to.getDisplayName(DefaultNameFormatter.getInstance()),
+                    intersect.getDisplayName(DefaultNameFormatter.getInstance())
+                );
+        }
         switch(role){
         case FROM:
-            msg = tr("The OSM way <span class=\"object-name\">{0}</span> with role <tt>{1}</tt> should be split "
+        	/*
+        	 * "to" joins "from" at a common node. Only from has to be split
+        	 */
+            msg = tr("The way <span class=\"object-name\">{0}</span> with role <tt>{1}</tt> should be split "
                 + "at node <span class=\"object-name\">{2}</span> where it connects to way <span class=\"object-name\">{3}</span>.",
                 from.getDisplayName(DefaultNameFormatter.getInstance()),
                 role.getOsmRole(),
-                interesect.getDisplayName(DefaultNameFormatter.getInstance()),
+                intersect.getDisplayName(DefaultNameFormatter.getInstance()),
                 to.getDisplayName(DefaultNameFormatter.getInstance())
             );
             break;
         case TO:
-            msg = tr("The OSM way <span class=\"object-name\">{0}</span> with role <tt>{1}</tt> should be split "
+        	/*
+        	 * "from" joins "to" at a common node. Only to has to be split
+        	 */
+            msg = tr("The way <span class=\"object-name\">{0}</span> with role <tt>{1}</tt> should be split "
                     + "at node <span class=\"object-name\">{2}</span> where it connects to way <span class=\"object-name\">{3}</span>.",
                     to.getDisplayName(DefaultNameFormatter.getInstance()),
                     role.getOsmRole(),
-                    interesect.getDisplayName(DefaultNameFormatter.getInstance()),
+                    intersect.getDisplayName(DefaultNameFormatter.getInstance()),
                     from.getDisplayName(DefaultNameFormatter.getInstance())
                 );
@@ -75,21 +126,55 @@
         public SplitAction() {
             putValue(NAME, tr("Split now"));
-            putValue(SHORT_DESCRIPTION, tr("Splits the way"));
+            putValue(SHORT_DESCRIPTION, tr("Split the ways"));
         }
+        
         public void actionPerformed(ActionEvent e) {
-            Way way = null;
-            switch(role){
-            case FROM: way = from; break;
-            case TO: way = to; break;
+
+        	SplitWayResult result = null;
+            if (role == null || role.equals(TurnRestrictionLegRole.FROM)){
+            	  result = SplitWayAction.split(
+                          parent.getEditorModel().getLayer(),
+                          from,
+                          Collections.singletonList(intersect),
+                          Collections.<OsmPrimitive>emptyList()
+                  );
+            	  if (result != null){
+                      Main.main.undoRedo.add(result.getCommand());
+                  }
             }
-            SplitWayResult result = SplitWayAction.split(
-                    parent.getEditorModel().getLayer(),
-                    way,
-                    Collections.singletonList(interesect),
-                    Collections.<OsmPrimitive>emptyList()
-            );
-            if (result != null){
-                Main.main.undoRedo.add(result.getCommand());
-            }
+            
+            if (role == null || role.equals(TurnRestrictionLegRole.TO)) {
+            	result = SplitWayAction.split(
+                        parent.getEditorModel().getLayer(),
+                        to,
+                        Collections.singletonList(intersect),
+                        Collections.<OsmPrimitive>emptyList()
+                );
+            	if (result != null){
+                    Main.main.undoRedo.add(result.getCommand());
+                }
+            	if (result == null) return;
+	        	TurnRestrictionType restrictionType = TurnRestrictionType.fromTagValue(getIssuesModel().getEditorModel().getRestrictionTagValue());
+	            if (restrictionType == null) return;
+	            Way adjustedTo = TurnRestrictionBuilder.selectToWayAfterSplit(
+	            		 from,
+	            		 result.getOriginalWay(),
+	            		 result.getNewWays().get(0),
+	            		 restrictionType
+	            );
+	
+	            if (adjustedTo == null) return;
+	            getIssuesModel().getEditorModel().setTurnRestrictionLeg(
+	            		 TurnRestrictionLegRole.TO,
+	            		 adjustedTo
+	            );	     
+	            getIssuesModel().getEditorModel().getLayer().data.setSelected(
+	              		 Arrays.asList(from, adjustedTo)
+	             );	
+            } else {
+	            getIssuesModel().getEditorModel().getLayer().data.setSelected(
+	              		 Arrays.asList(from, to)
+	             );	            	
+            }           
         }
     }
Index: /applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/WrongTurnRestrictionLegTypeError.java
===================================================================
--- /applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/WrongTurnRestrictionLegTypeError.java	(revision 23592)
+++ /applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/WrongTurnRestrictionLegTypeError.java	(revision 23593)
@@ -43,5 +43,5 @@
         case NODE:
             msg = tr(
-                "This turn restriction uses the OSM node <span class=\"object-name\">{0}</span> as member with role <tt>{1}</tt>.",
+                "This turn restriction uses the node <span class=\"object-name\">{0}</span> as member with role <tt>{1}</tt>.",
                 leg.getDisplayName(DefaultNameFormatter.getInstance()),
                 role.toString()
@@ -49,5 +49,5 @@
             break;
         case RELATION:
-            msg = tr("This turn restriction uses the OSM relation <span class=\"object-name\">{0}</span> as member with role <tt>{1}</tt>.",
+            msg = tr("This turn restriction uses the relation <span class=\"object-name\">{0}</span> as member with role <tt>{1}</tt>.",
                     leg.getDisplayName(DefaultNameFormatter.getInstance()),
                     role.toString()
@@ -55,5 +55,5 @@
             break;          
         }
-        return msg + " " + tr("An OSM way is required instead.");
+        return msg + " " + tr("A way is required instead.");
     }
 
@@ -79,5 +79,5 @@
         public FixInEditorAction() {
             putValue(NAME, tr("Fix in editor"));
-            putValue(SHORT_DESCRIPTION, tr("Change to the Basic Editor and select an OSM way"));
+            putValue(SHORT_DESCRIPTION, tr("Change to the Basic Editor and select a way"));
         }
         public void actionPerformed(ActionEvent e) {
Index: /applications/editors/josm/plugins/turnrestrictions/test/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionBuilderTest.groovy
===================================================================
--- /applications/editors/josm/plugins/turnrestrictions/test/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionBuilderTest.groovy	(revision 23592)
+++ /applications/editors/josm/plugins/turnrestrictions/test/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionBuilderTest.groovy	(revision 23593)
@@ -1,3 +1,6 @@
 package org.openstreetmap.josm.plugins.turnrestrictions;
+
+import java.util.Arrays;
+
 import groovy.util.GroovyTestCase;
 
@@ -10,4 +13,6 @@
 import org.openstreetmap.josm.plugins.turnrestrictions.fixtures.JOSMFixture;
 import org.openstreetmap.josm.data.coor.LatLon;
+import static org.openstreetmap.josm.plugins.turnrestrictions.TurnRestrictionBuilder.*
+import org.openstreetmap.josm.plugins.turnrestrictions.editor.TurnRestrictionType;
 
 class TurnRestrictionBuilderTest{
@@ -33,13 +38,5 @@
 	public void setUp() {
 		JOSMFixture.createUnitTestFixture().init()
-		builder = new TurnRestrictionBuilder() {
-			def double testPhi(Way w){
-				return super.phi(w)
-			}
-			
-			def double testPhi(Way w, boolean doRevert){
-				return super.phi(w,doRevert)
-			}
-		}
+		builder = new TurnRestrictionBuilder()
 	}
 
@@ -168,6 +165,6 @@
 	   w2.setNodes([n2,n3])
 
-	   assert builder.testPhi(w1) == Math.toRadians(90)	   
-	   assert builder.testPhi(w2) == Math.toRadians(0)
+	   assert builder.phi(w1) == Math.toRadians(90)	   
+	   assert builder.phi(w2) == Math.toRadians(0)
 	   	   
 	   Relation tr = builder.build([w1,w2,n2])
@@ -187,4 +184,7 @@
 	   
 	   tr = builder.build([w2,w1,n2])
+	   
+	   double a = interesectionAngle(w2, w1)
+	   println "a=" + Math.toDegrees(a)
 	   
 	   assert tr != null
@@ -223,7 +223,7 @@
 	   w2.setNodes([n3,n2])
 	   
-	   assert builder.testPhi(w1) == Math.toRadians(90)
-	   assert builder.testPhi(w2) == Math.toRadians(0)
-	   assert builder.testPhi(w2,true) == Math.toRadians(180)
+	   assert builder.phi(w1) == Math.toRadians(90)
+	   assert builder.phi(w2) == Math.toRadians(0)
+	   assert builder.phi(w2,true) == Math.toRadians(180)
 	   
 	   Relation tr = builder.build([w1,w2,n2])
@@ -237,5 +237,4 @@
 	   
 	   assert tr.get("restriction") == "no_left_turn"
-	   
 	   
 	   /*
@@ -348,3 +347,299 @@
 	 assert tr.get("restriction") == "no_left_turn"
 	}
+ 
+ 
+    def Node nn(id, lat, lon) {
+		Node n = new Node(id)
+		n.setCoor(new LatLon(lat, lon))
+		return n
+    }
+	
+	def Way nw(id, Node... nodes) {
+		Way w = new Way(id)
+		w.setNodes(Arrays.asList(nodes))
+		return w
+	}
+ 
+ 	/** 
+ 	 *                              n3
+ 	 *                           (10,10)
+ 	 *                             ^
+ 	 *                             | to
+ 	 *      n1      from           |
+ 	 *    (5,5) -------------->  (5,10) n2
+ 	 */
+	 @Test
+	 public void intersectionAngle_1() {
+		 Node n1 = nn(1,5,5)
+		 Node n2 = nn(2,5,10)
+		 Node n3 = nn(3,10,10)
+		 Way from = nw(1,n1,n2)
+		 Way to = nw(2,n2,n3)
+		 
+		 double a = TurnRestrictionBuilder.interesectionAngle(from, to)
+		 RelativeWayJoinOrientation o = TurnRestrictionBuilder.determineWayJoinOrientation(from,to)
+		 assert Math.toDegrees(a) == -90
+		 assert o == RelativeWayJoinOrientation.LEFT
+		 
+		 /*
+		  * if reversed from, the intersection angle is still -90°
+		  */
+		 from = nw(1,n2,n1)
+		 to = nw(2,n2,n3)
+		 a = TurnRestrictionBuilder.interesectionAngle(from, to)
+		 o = TurnRestrictionBuilder.determineWayJoinOrientation(from,to)
+		 assert Math.toDegrees(a) == -90
+		 assert o == RelativeWayJoinOrientation.LEFT
+
+		 /*
+		 * if reversed to, the intersection angle is still -90°
+		 */
+		 from = nw(1,n1,n2)
+		 to = nw(2,n3,n2)
+		 a = TurnRestrictionBuilder.interesectionAngle(from, to)
+		 o = TurnRestrictionBuilder.determineWayJoinOrientation(from,to)
+		 assert Math.toDegrees(a) == -90
+		 assert o == RelativeWayJoinOrientation.LEFT
+
+		 /*
+		 * if reversed both, the intersection angle is still -90°
+		 */
+		 from = nw(1,n2,n1)
+		 to = nw(2,n3,n2)
+		 a = TurnRestrictionBuilder.interesectionAngle(from, to)
+		 o = TurnRestrictionBuilder.determineWayJoinOrientation(from,to)
+		 assert Math.toDegrees(a) == -90
+		 assert o == RelativeWayJoinOrientation.LEFT
+	 }
+	 
+	 /**
+	 *      n1      from           
+	 *    (5,5) -------------->  (5,10) n2
+	 *                              |
+	 *                              | to
+	 *                              |
+	 *                              v
+	 *                            (2,10)
+	 *                              n3
+	 *    
+	 */
+	@Test
+	public void intersectionAngle_2() {
+		Node n1 = nn(1,5,5)
+		Node n2 = nn(2,5,10)
+		Node n3 = nn(3,2,10)
+		Way from = nw(1,n1,n2)
+		Way to = nw(2,n2,n3)
+		
+		double a = TurnRestrictionBuilder.interesectionAngle(from, to)
+		assert Math.toDegrees(a) == 90
+		
+		/*
+		 * if reversed from, the intersection angle is still 90°
+		 */
+		from = nw(1,n2,n1)
+		to = nw(2,n2,n3)
+		a = TurnRestrictionBuilder.interesectionAngle(from, to)
+		assert Math.toDegrees(a) == 90
+
+		/*
+		* if reversed to, the intersection angle is still 90°
+		*/
+		from = nw(1,n1,n2)
+		to = nw(2,n3,n2)
+		a = TurnRestrictionBuilder.interesectionAngle(from, to)
+		assert Math.toDegrees(a) == 90
+
+		/*
+		* if reversed both, the intersection angle is still 90°
+		*/
+		from = nw(1,n2,n1)
+		to = nw(2,n3,n2)
+		a = TurnRestrictionBuilder.interesectionAngle(from, to)
+		assert Math.toDegrees(a) == 90
+	}
+	
+	
+	/**
+	 * 
+	 *                       
+	 *             (-1,-6) (n3)
+	 *             ^
+	 *            /
+	 *           /  to
+	 *          /
+	 *      (-5, -10) n2
+    *           ^
+	*           |
+	*           | from 
+	*           |
+	*       (-10,-10) n1 
+	*/
+   @Test
+   public void intersectionAngle_3() {
+	   Node n1 = nn(1,-10,-10)
+	   Node n2 = nn(2,-5,-10)
+	   Node n3 = nn(3,-1,-6)
+	   Way from = nw(1,n1,n2)
+	   Way to = nw(2,n2,n3)
+	   
+	   double a = TurnRestrictionBuilder.interesectionAngle(from, to)
+	   assert Math.toDegrees(a) == 45
+	   
+	   /*
+		* if reversed from, the intersection angle is still 45
+		*/
+	   from = nw(1,n2,n1)
+	   to = nw(2,n2,n3)
+	   a = TurnRestrictionBuilder.interesectionAngle(from, to)
+	   assert Math.toDegrees(a) == 45
+
+	   /*
+	   * if reversed to, the intersection angle is still 45
+	   */
+	   from = nw(1,n1,n2)
+	   to = nw(2,n3,n2)
+	   a = TurnRestrictionBuilder.interesectionAngle(from, to)
+	   assert Math.toDegrees(a) == 45
+
+	   /*
+	   * if reversed both, the intersection angle is still 45
+	   */
+	   from = nw(1,n2,n1)
+	   to = nw(2,n3,n2)
+	   a = TurnRestrictionBuilder.interesectionAngle(from, to)
+	   assert Math.toDegrees(a) == 45
+   }
+   
+   /**
+   *
+   *
+   *         (-1,-14) (n3)
+   *            ^
+   *            \
+   *             \ to
+   *              \
+   *          (-5, -10) n2
+  *               ^
+  *               |
+  *               | from
+  *               |
+  *           (-10,-10) n1
+  */
+ @Test
+ public void intersectionAngle_4() {
+	 Node n1 = nn(1,-10,-10)
+	 Node n2 = nn(2,-5,-10)
+	 Node n3 = nn(3,-1,-14)
+	 Way from = nw(1,n1,n2)
+	 Way to = nw(2,n2,n3)
+	 
+	 double a = TurnRestrictionBuilder.interesectionAngle(from, to)
+	 assert Math.toDegrees(a) == -45
+	 
+	 /*
+	  * if reversed from, the intersection angle is still -45
+	  */
+	 from = nw(1,n2,n1)
+	 to = nw(2,n2,n3)
+	 a = TurnRestrictionBuilder.interesectionAngle(from, to)
+	 assert Math.toDegrees(a) == -45
+
+	 /*
+	 * if reversed to, the intersection angle is still -45
+	 */
+	 from = nw(1,n1,n2)
+	 to = nw(2,n3,n2)
+	 a = TurnRestrictionBuilder.interesectionAngle(from, to)
+	 assert Math.toDegrees(a) == -45
+
+	 /*
+	 * if reversed both, the intersection angle is still 45
+	 */
+	 from = nw(1,n2,n1)
+	 to = nw(2,n3,n2)
+	 a = TurnRestrictionBuilder.interesectionAngle(from, to)
+	 assert Math.toDegrees(a) == -45
+ }
+ 
+ 
+	 /*
+	 *
+	 *      n21        w21        n22       w22            n23
+	 *    (10,10)-------------> (10,15) -------------- > (10,20)
+	 *                            ^
+	 *                            |
+	 *                            | w1
+	 *                            |
+	 *                          (5,15)
+	 *                            n11
+	 */
+	@Test
+	public void splitToWay() {
+		Node n11 = new Node(11);
+		n11.setCoor(new LatLon(5,15));
+		
+		Node n21 = new Node(21)
+		n21.setCoor(new LatLon(10,10))
+		Node n22 = new Node(22)
+		n22.setCoor(new LatLon(10,15))
+		Node n23 = new Node(23)
+		n23.setCoor(new LatLon(10,20))
+		
+		Way w1 = new Way(1)
+		w1.setNodes([n11,n22])
+		Way w21 = new Way(21)
+		w21.setNodes([n21,n22])
+		Way w22 = new Way(22)
+		w22.setNodes([n22,n23])
+	
+		Way adjustedTo = selectToWayAfterSplit(
+			w1,
+			w21,
+			w22,
+			TurnRestrictionType.NO_LEFT_TURN
+		)
+		
+		assert adjustedTo != null
+		assert adjustedTo == w21
+		
+		adjustedTo = selectToWayAfterSplit(
+			w1,
+			w21,
+			w22,
+			TurnRestrictionType.NO_RIGHT_TURN
+		)
+		
+		assert adjustedTo != null
+		assert adjustedTo == w22
+		
+		adjustedTo = selectToWayAfterSplit(
+			w1,
+			w21,
+			w22,
+			TurnRestrictionType.ONLY_LEFT_TURN
+		)
+		
+		assert adjustedTo != null
+		assert adjustedTo == w21
+		
+		adjustedTo = selectToWayAfterSplit(
+			w1,
+			w21,
+			w22,
+			TurnRestrictionType.ONLY_RIGHT_TURN
+		)
+		
+		assert adjustedTo != null
+		assert adjustedTo == w22
+		
+		adjustedTo = selectToWayAfterSplit(
+			w1,
+			w21,
+			w22,
+			TurnRestrictionType.NO_STRAIGHT_ON
+		)
+		
+		assert adjustedTo == null
+	}	
 }
