Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/PTAssistantPlugin.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/PTAssistantPlugin.java	(revision 33416)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/PTAssistantPlugin.java	(revision 33417)
@@ -105,5 +105,5 @@
         lastFix = segment;
         SwingUtilities.invokeLater(() ->
-        	repeatLastFixMenu.setEnabled(segment != null));
+        repeatLastFixMenu.setEnabled(segment != null));
     }
 
@@ -117,20 +117,20 @@
     }
 
-	public static List<Relation> getHighlightedRelations() {
-		return new ArrayList<>(highlightedRelations);
-	}
+    public static List<Relation> getHighlightedRelations() {
+        return new ArrayList<>(highlightedRelations);
+    }
 
-	public static void addHighlightedRelation(Relation highlightedRelation) {
-		highlightedRelations.add(highlightedRelation);
-		if(!editHighlightedRelationsMenu.isEnabled()) {
-			SwingUtilities.invokeLater(() ->
-				editHighlightedRelationsMenu.setEnabled(true));
-		}
-	}
+    public static void addHighlightedRelation(Relation highlightedRelation) {
+        highlightedRelations.add(highlightedRelation);
+        if(!editHighlightedRelationsMenu.isEnabled()) {
+            SwingUtilities.invokeLater(() ->
+            editHighlightedRelationsMenu.setEnabled(true));
+        }
+    }
 
-	public static void clearHighlightedRelations() {
-		highlightedRelations.clear();
-		SwingUtilities.invokeLater(() ->
-            	editHighlightedRelationsMenu.setEnabled(false));
-	}
+    public static void clearHighlightedRelations() {
+        highlightedRelations.clear();
+        SwingUtilities.invokeLater(() ->
+        editHighlightedRelationsMenu.setEnabled(false));
+    }
 }
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/AddStopPositionAction.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/AddStopPositionAction.java	(revision 33416)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/AddStopPositionAction.java	(revision 33417)
@@ -33,8 +33,8 @@
 public class AddStopPositionAction extends MapMode {
 
-	private static final String mapModeName = "Add stop position";
+    private static final String mapModeName = "Add stop position";
 
-	private transient Set<OsmPrimitive> newHighlights = new HashSet<>();
-	private transient Set<OsmPrimitive> oldHighlights = new HashSet<>();
+    private transient Set<OsmPrimitive> newHighlights = new HashSet<>();
+    private transient Set<OsmPrimitive> oldHighlights = new HashSet<>();
 
     private final Cursor cursorJoinNode;
@@ -44,20 +44,20 @@
      * Creates a new AddStopPositionAction
      */
-	public AddStopPositionAction() {
-		super(tr(mapModeName), "bus", tr(mapModeName),
-				Shortcut.registerShortcut("mapmode:stop_position",
+    public AddStopPositionAction() {
+        super(tr(mapModeName), "bus", tr(mapModeName),
+                Shortcut.registerShortcut("mapmode:stop_position",
                         tr("Mode: {0}", tr(mapModeName)),
                         KeyEvent.VK_K, Shortcut.CTRL_SHIFT),
-				getCursor());
+                getCursor());
 
-		cursorJoinNode = ImageProvider.getCursor("crosshair", "joinnode");
+        cursorJoinNode = ImageProvider.getCursor("crosshair", "joinnode");
         cursorJoinWay = ImageProvider.getCursor("crosshair", "joinway");
-	}
+    }
 
     private static Cursor getCursor() {
-    	Cursor cursor = ImageProvider.getCursor("crosshair", "bus");
-    	if(cursor == null)
-    		cursor = Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR);
-    	return cursor;
+        Cursor cursor = ImageProvider.getCursor("crosshair", "bus");
+        if(cursor == null)
+            cursor = Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR);
+        return cursor;
     }
 
@@ -79,27 +79,27 @@
     public void mouseMoved(MouseEvent e) {
 
-    	//while the mouse is moving, surroundings are checked
-    	//if anything is found, it will be highlighted.
-    	//priority is given to nodes
-    	Cursor newCurs = getCursor();
+        //while the mouse is moving, surroundings are checked
+        //if anything is found, it will be highlighted.
+        //priority is given to nodes
+        Cursor newCurs = getCursor();
 
-    	Node n = Main.map.mapView.getNearestNode(e.getPoint(), OsmPrimitive::isUsable);
-    	if(n != null) {
-    		newHighlights.add(n);
-    		newCurs = cursorJoinNode;
-    	} else {
-    		List<WaySegment> wss =
-    				Main.map.mapView.getNearestWaySegments(e.getPoint(), OsmPrimitive::isSelectable);
+        Node n = Main.map.mapView.getNearestNode(e.getPoint(), OsmPrimitive::isUsable);
+        if(n != null) {
+            newHighlights.add(n);
+            newCurs = cursorJoinNode;
+        } else {
+            List<WaySegment> wss =
+                    Main.map.mapView.getNearestWaySegments(e.getPoint(), OsmPrimitive::isSelectable);
 
-    		if(!wss.isEmpty()) {
-	    		for(WaySegment ws : wss) {
-	    			newHighlights.add(ws.way);
-	    		}
-	    		newCurs = cursorJoinWay;
-    		}
-		}
+            if(!wss.isEmpty()) {
+                for(WaySegment ws : wss) {
+                    newHighlights.add(ws.way);
+                }
+                newCurs = cursorJoinWay;
+            }
+        }
 
-    	Main.map.mapView.setCursor(newCurs);
-    	updateHighlights();
+        Main.map.mapView.setCursor(newCurs);
+        updateHighlights();
     }
 
@@ -107,35 +107,35 @@
     public void mouseClicked(MouseEvent e) {
 
-    	Boolean newNode = false;
-    	Node newStopPos;
+        Boolean newNode = false;
+        Node newStopPos;
 
-    	//check if the user as selected an existing node, or a new one
-    	Node n = Main.map.mapView.getNearestNode(e.getPoint(), OsmPrimitive::isUsable);
+        //check if the user as selected an existing node, or a new one
+        Node n = Main.map.mapView.getNearestNode(e.getPoint(), OsmPrimitive::isUsable);
         if (n == null) {
-        	newNode = true;
-        	newStopPos = new Node(Main.map.mapView.getLatLon(e.getX(), e.getY()));
+            newNode = true;
+            newStopPos = new Node(Main.map.mapView.getLatLon(e.getX(), e.getY()));
         } else {
-        	newStopPos = new Node(n);
+            newStopPos = new Node(n);
             clearNodeTags(newStopPos);
         }
 
         //add the tags of the stop position
-    	newStopPos.put("bus", "yes");
-    	newStopPos.put("public_transport", "stop_position");
+        newStopPos.put("bus", "yes");
+        newStopPos.put("public_transport", "stop_position");
 
-    	if(newNode) {
-    		Main.main.undoRedo.add(new AddCommand(newStopPos));
-    	} else {
-    		Main.main.undoRedo.add(new ChangeCommand(n, newStopPos));
-    	}
+        if(newNode) {
+            Main.main.undoRedo.add(new AddCommand(newStopPos));
+        } else {
+            Main.main.undoRedo.add(new ChangeCommand(n, newStopPos));
+        }
 
-    	DataSet ds = Main.getLayerManager().getEditLayer().data;
-    	ds.setSelected(newStopPos);
+        DataSet ds = Main.getLayerManager().getEditLayer().data;
+        ds.setSelected(newStopPos);
 
-    	//join the node to the way only if the node is new
-    	if(newNode) {
-	        JoinNodeWayAction joinNodeWayAction = JoinNodeWayAction.createJoinNodeToWayAction();
-	        joinNodeWayAction.actionPerformed(null);
-    	}
+        //join the node to the way only if the node is new
+        if(newNode) {
+            JoinNodeWayAction joinNodeWayAction = JoinNodeWayAction.createJoinNodeToWayAction();
+            joinNodeWayAction.actionPerformed(null);
+        }
 
         // split the way in any case
@@ -145,30 +145,30 @@
 
     private void clearNodeTags(Node newStopPos) {
-		for(String key : newStopPos.keySet()) {
-			newStopPos.put(key, null);
-		}
+        for(String key : newStopPos.keySet()) {
+            newStopPos.put(key, null);
+        }
 
-	}
+    }
 
-	//turn off what has been highlighted on last mouse move and highlight what has to be highlighted now
+    //turn off what has been highlighted on last mouse move and highlight what has to be highlighted now
     private void updateHighlights()
     {
-    	if(oldHighlights.isEmpty() && newHighlights.isEmpty()) {
-    		return;
-    	}
+        if(oldHighlights.isEmpty() && newHighlights.isEmpty()) {
+            return;
+        }
 
-		for(OsmPrimitive osm : oldHighlights) {
-    		osm.setHighlighted(false);
-    	}
+        for(OsmPrimitive osm : oldHighlights) {
+            osm.setHighlighted(false);
+        }
 
-    	for(OsmPrimitive osm : newHighlights) {
-    		osm.setHighlighted(true);
-    	}
+        for(OsmPrimitive osm : newHighlights) {
+            osm.setHighlighted(true);
+        }
 
-		Main.getLayerManager().getEditLayer().invalidate();
+        Main.getLayerManager().getEditLayer().invalidate();
 
-    	oldHighlights.clear();
-    	oldHighlights.addAll(newHighlights);
-    	newHighlights.clear();
+        oldHighlights.clear();
+        oldHighlights.addAll(newHighlights);
+        newHighlights.clear();
     }
 }
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/EdgeSelectionAction.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/EdgeSelectionAction.java	(revision 33416)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/EdgeSelectionAction.java	(revision 33417)
@@ -30,23 +30,23 @@
 public class EdgeSelectionAction extends MapMode {
 
-	private static final String mapModeName = "Edge Selection";
-	private static final long serialVersionUID = 2414977774504904238L;
+    private static final String mapModeName = "Edge Selection";
+    private static final long serialVersionUID = 2414977774504904238L;
 
-	private transient  Set<Way> highlighted;
+    private transient  Set<Way> highlighted;
 
-	private Cursor selectionCursor;
-	private Cursor waySelectCursor;
+    private Cursor selectionCursor;
+    private Cursor waySelectCursor;
 
-	public EdgeSelectionAction() {
-		super(tr(mapModeName), "edgeSelection", tr(mapModeName),
-				Shortcut.registerShortcut("mapmode:edge_selection",
+    public EdgeSelectionAction() {
+        super(tr(mapModeName), "edgeSelection", tr(mapModeName),
+                Shortcut.registerShortcut("mapmode:edge_selection",
                         tr("Mode: {0}", tr(mapModeName)),
                         KeyEvent.VK_K, Shortcut.CTRL),
-				ImageProvider.getCursor("normal", "selection"));
-		highlighted = new HashSet<>();
+                ImageProvider.getCursor("normal", "selection"));
+        highlighted = new HashSet<>();
 
-		selectionCursor = ImageProvider.getCursor("normal", "selection");
-		waySelectCursor = ImageProvider.getCursor("normal", "select_way");
-	}
+        selectionCursor = ImageProvider.getCursor("normal", "selection");
+        waySelectCursor = ImageProvider.getCursor("normal", "select_way");
+    }
 
     /*
@@ -55,37 +55,37 @@
      */
     private List<Way> getEdgeFromWay(Way initial, String modeOfTravel) {
-    	List<Way> edge = new ArrayList<>();
-    	if(!isWaySuitableForMode(initial, modeOfTravel))
-    		return edge;
+        List<Way> edge = new ArrayList<>();
+        if(!isWaySuitableForMode(initial, modeOfTravel))
+            return edge;
 
-    	Way curr = initial;
-    	while(true) {
-    		List<Way> options = curr.firstNode(true).getParentWays();
-    		options.remove(curr);
-    		curr = chooseBestWay(options, modeOfTravel);
-    		if(curr == null || edge.contains(curr))
-    			break;
-    		edge.add(curr);
-    	}
+        Way curr = initial;
+        while(true) {
+            List<Way> options = curr.firstNode(true).getParentWays();
+            options.remove(curr);
+            curr = chooseBestWay(options, modeOfTravel);
+            if(curr == null || edge.contains(curr))
+                break;
+            edge.add(curr);
+        }
 
-    	curr = initial;
-    	while(true) {
-    		List<Way> options = curr.lastNode(true).getParentWays();
-    		options.remove(curr);
-    		curr = chooseBestWay(options, modeOfTravel);
-    		if(curr == null || edge.contains(curr))
-    			break;
-    		edge.add(curr);
-    	}
+        curr = initial;
+        while(true) {
+            List<Way> options = curr.lastNode(true).getParentWays();
+            options.remove(curr);
+            curr = chooseBestWay(options, modeOfTravel);
+            if(curr == null || edge.contains(curr))
+                break;
+            edge.add(curr);
+        }
 
-    	edge.add(initial);
-    	return edge;
+        edge.add(initial);
+        return edge;
     }
 
     private Boolean isWaySuitableForMode(Way toCheck, String modeOfTravel) {
-    	if("bus".equals(modeOfTravel))
-    		return RouteUtils.isWaySuitableForBuses(toCheck);
+        if("bus".equals(modeOfTravel))
+            return RouteUtils.isWaySuitableForBuses(toCheck);
 
-    	return RouteUtils.isWaySuitableForPublicTransport(toCheck);
+        return RouteUtils.isWaySuitableForPublicTransport(toCheck);
     }
 
@@ -94,61 +94,61 @@
      */
     private Way chooseBestWay(List<Way> ways, String modeOfTravel) {
-    	ways.removeIf(w -> !isWaySuitableForMode(w, modeOfTravel));
-    	if(ways.isEmpty())
-    		return null;
-    	if(ways.size() == 1)
-    		return ways.get(0);
+        ways.removeIf(w -> !isWaySuitableForMode(w, modeOfTravel));
+        if(ways.isEmpty())
+            return null;
+        if(ways.size() == 1)
+            return ways.get(0);
 
-    	Way theChoosenOne = null;
+        Way theChoosenOne = null;
 
-    	if("bus".equals(modeOfTravel))
-    	{
+        if("bus".equals(modeOfTravel))
+        {
 
-    	}
-    	if("tram".equals(modeOfTravel))
-    	{
+        }
+        if("tram".equals(modeOfTravel))
+        {
 
-    	}
+        }
 
-    	return theChoosenOne;
+        return theChoosenOne;
     }
 
     private String getModeOfTravel() {
-    	//find a way to get the currently opened relation editor and get the
-    	//from there the current type of route
-		return "bus";
-	}
+        //find a way to get the currently opened relation editor and get the
+        //from there the current type of route
+        return "bus";
+    }
 
-	@Override
+    @Override
     public void mouseClicked(MouseEvent e) {
 
-		DataSet ds = Main.getLayerManager().getEditLayer().data;
-    	Way initial = Main.map.mapView.getNearestWay(e.getPoint(), OsmPrimitive::isUsable);
-    	if(initial != null){
-    		ds.setSelected(getEdgeFromWay(initial, getModeOfTravel()));
-    	}
-    	else
-    		ds.clearSelection();
+        DataSet ds = Main.getLayerManager().getEditLayer().data;
+        Way initial = Main.map.mapView.getNearestWay(e.getPoint(), OsmPrimitive::isUsable);
+        if(initial != null){
+            ds.setSelected(getEdgeFromWay(initial, getModeOfTravel()));
+        }
+        else
+            ds.clearSelection();
     }
 
     @Override
     public void mouseMoved(MouseEvent e) {
-    	super.mouseMoved(e);
+        super.mouseMoved(e);
 
-    	for(Way way : highlighted)
-    		way.setHighlighted(false);
-    	highlighted.clear();
+        for(Way way : highlighted)
+            way.setHighlighted(false);
+        highlighted.clear();
 
-    	Way initial = Main.map.mapView.getNearestWay(e.getPoint(), OsmPrimitive::isUsable);
-    	if(initial == null) {
-    		Main.map.mapView.setCursor(selectionCursor);
-    	}
-    	else {
-    		Main.map.mapView.setCursor(waySelectCursor);
-    		highlighted.addAll(getEdgeFromWay(initial, getModeOfTravel()));
-    	}
+        Way initial = Main.map.mapView.getNearestWay(e.getPoint(), OsmPrimitive::isUsable);
+        if(initial == null) {
+            Main.map.mapView.setCursor(selectionCursor);
+        }
+        else {
+            Main.map.mapView.setCursor(waySelectCursor);
+            highlighted.addAll(getEdgeFromWay(initial, getModeOfTravel()));
+        }
 
-    	for(Way way : highlighted)
-    		way.setHighlighted(true);
+        for(Way way : highlighted)
+            way.setHighlighted(true);
     }
 
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/EditHighlightedRelationsAction.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/EditHighlightedRelationsAction.java	(revision 33416)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/EditHighlightedRelationsAction.java	(revision 33417)
@@ -33,5 +33,5 @@
         super(tr(actionName), new ImageProvider("dialogs", "edit"), tr(actionName),
                 Shortcut.registerShortcut("Edit Highlighted Relation", tr(actionName),
-                		KeyEvent.VK_K, Shortcut.ALT),
+                        KeyEvent.VK_K, Shortcut.ALT),
                 false, "editHighlightedRelations", false);
     }
@@ -39,9 +39,9 @@
     @Override
     public void actionPerformed(ActionEvent e) {
-    	for(Relation relation : PTAssistantPlugin.getHighlightedRelations()) {
-    		RelationEditor editor = RelationEditor.getEditor(
-    				Main.getLayerManager().getEditLayer(), relation, null);
+        for(Relation relation : PTAssistantPlugin.getHighlightedRelations()) {
+            RelationEditor editor = RelationEditor.getEditor(
+                    Main.getLayerManager().getEditLayer(), relation, null);
             editor.setVisible(true);
-    	}
+        }
     }
 
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/SplitRoundaboutAction.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/SplitRoundaboutAction.java	(revision 33416)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/SplitRoundaboutAction.java	(revision 33417)
@@ -111,5 +111,5 @@
         List<Node> splitNodes = getSplitNodes(roundabout);
         SplitWayResult result = SplitWayAction.split(getLayerManager().getEditLayer(),
-        		roundabout, splitNodes, Collections.emptyList());
+                roundabout, splitNodes, Collections.emptyList());
         Main.main.undoRedo.add(result.getCommand());
         Collection<Way> splitWays = result.getNewWays();
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/data/PTRouteSegment.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/data/PTRouteSegment.java	(revision 33416)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/data/PTRouteSegment.java	(revision 33417)
@@ -187,6 +187,6 @@
     public boolean equalsRouteSegment(PTRouteSegment other) {
 
-//    	if(!firstStop.equalsStop(firstStop) || !lastStop.equalsStop(other.lastStop))
-//    		return false;
+//      if(!firstStop.equalsStop(firstStop) || !lastStop.equalsStop(other.lastStop))
+//          return false;
 
         List<Way> thisWays = new ArrayList<>();
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/PTAssistantLayer.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/PTAssistantLayer.java	(revision 33416)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/PTAssistantLayer.java	(revision 33417)
@@ -128,6 +128,6 @@
     public void setPrimitives(List<OsmPrimitive> primitives)
     {
-    	this.primitives.clear();
-    	this.primitives.addAll(primitives);
+        this.primitives.clear();
+        this.primitives.addAll(primitives);
     }
 
@@ -267,6 +267,6 @@
 
         if(event.getRemovedLayer() == this) {
-        	PTAssistantLayerManager.PTLM.resetLayer();
-        	PTAssistantPlugin.clearHighlightedRelations();
+            PTAssistantLayerManager.PTLM.resetLayer();
+            PTAssistantPlugin.clearHighlightedRelations();
         }
     }
@@ -274,7 +274,7 @@
     @Override
     public synchronized void destroy() {
-    	KeyboardFocusManager.getCurrentKeyboardFocusManager().removePropertyChangeListener(this);
+        KeyboardFocusManager.getCurrentKeyboardFocusManager().removePropertyChangeListener(this);
         Main.getLayerManager().removeLayerChangeListener(this);
-    	super.destroy();
+        super.destroy();
     }
 }
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/PTAssistantLayerManager.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/PTAssistantLayerManager.java	(revision 33416)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/PTAssistantLayerManager.java	(revision 33417)
@@ -14,6 +14,6 @@
 public class PTAssistantLayerManager implements SelectionChangedListener {
 
-	public final static PTAssistantLayerManager PTLM = new PTAssistantLayerManager();
-	private PTAssistantLayer layer;
+    public final static PTAssistantLayerManager PTLM = new PTAssistantLayerManager();
+    private PTAssistantLayer layer;
 
     public PTAssistantLayer getLayer() {
@@ -25,5 +25,5 @@
 
     public void resetLayer() {
-    	layer = null;
+        layer = null;
     }
 
@@ -38,14 +38,14 @@
         for (OsmPrimitive primitive : newSelection) {
             if (primitive.getType().equals(OsmPrimitiveType.RELATION)
-            		&& RouteUtils.isVersionTwoPTRoute((Relation) primitive)) {
-            	routes.add(primitive);
+                    && RouteUtils.isVersionTwoPTRoute((Relation) primitive)) {
+                routes.add(primitive);
             }
         }
 
         if (!routes.isEmpty()) {
-        	getLayer().setPrimitives(routes);
-        	PTAssistantPlugin.clearHighlightedRelations();
-        	for(OsmPrimitive primitive : routes)
-        		PTAssistantPlugin.addHighlightedRelation((Relation) primitive);
+            getLayer().setPrimitives(routes);
+            PTAssistantPlugin.clearHighlightedRelations();
+            for(OsmPrimitive primitive : routes)
+                PTAssistantPlugin.addHighlightedRelation((Relation) primitive);
         }
     }
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/PTAssistantPaintVisitor.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/PTAssistantPaintVisitor.java	(revision 33416)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/PTAssistantPaintVisitor.java	(revision 33417)
@@ -286,11 +286,11 @@
     @Override
     protected void drawNode(Node n, Color color) {
-		if (mv == null || g == null) {
-			return;
-		}
+        if (mv == null || g == null) {
+            ;
+        }
         Point p = mv.getPoint(n);
-		if (p == null) {
-			return;
-		}
+        if (p == null) {
+            return;
+        }
         g.setColor(color);
         g.drawOval(p.x - 5, p.y - 5, 10, 10);
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/utils/RouteUtils.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/utils/RouteUtils.java	(revision 33416)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/utils/RouteUtils.java	(revision 33417)
@@ -19,5 +19,5 @@
 public final class RouteUtils {
 
-	private final static String ptVersionTag = "public_transport:version";
+    private final static String ptVersionTag = "public_transport:version";
     private RouteUtils() {
         // private constructor for util classes
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/NodeChecker.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/NodeChecker.java	(revision 33416)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/NodeChecker.java	(revision 33417)
@@ -28,153 +28,153 @@
 public class NodeChecker extends Checker {
 
-	protected NodeChecker(Node node, Test test) {
-		super(node, test);
+    protected NodeChecker(Node node, Test test) {
+        super(node, test);
 
-	}
+    }
 
-	/**
-	 * Checks if the given stop_position node belongs to any way
-	 */
-	protected void performSolitaryStopPositionTest() {
+    /**
+     * Checks if the given stop_position node belongs to any way
+     */
+    protected void performSolitaryStopPositionTest() {
 
-		List<OsmPrimitive> referrers = node.getReferrers();
+        List<OsmPrimitive> referrers = node.getReferrers();
 
-		for (OsmPrimitive referrer : referrers) {
-			if (referrer.getType().equals(OsmPrimitiveType.WAY)) {
-				Way referrerWay = (Way) referrer;
-				if (RouteUtils.isWaySuitableForPublicTransport(referrerWay)) {
-					return;
-				}
+        for (OsmPrimitive referrer : referrers) {
+            if (referrer.getType().equals(OsmPrimitiveType.WAY)) {
+                Way referrerWay = (Way) referrer;
+                if (RouteUtils.isWaySuitableForPublicTransport(referrerWay)) {
+                    return;
+                }
 
-			}
-		}
+            }
+        }
 
-		List<OsmPrimitive> primitives = new ArrayList<>(1);
-		primitives.add(node);
-		Builder builder = TestError.builder(this.test, Severity.WARNING, PTAssistantValidatorTest.ERROR_CODE_SOLITARY_STOP_POSITION);
-		builder.message(tr("PT: Stop_position is not part of a way"));
-		builder.primitives(primitives);
-		TestError e = builder.build();
-		errors.add(e);
+        List<OsmPrimitive> primitives = new ArrayList<>(1);
+        primitives.add(node);
+        Builder builder = TestError.builder(this.test, Severity.WARNING, PTAssistantValidatorTest.ERROR_CODE_SOLITARY_STOP_POSITION);
+        builder.message(tr("PT: Stop_position is not part of a way"));
+        builder.primitives(primitives);
+        TestError e = builder.build();
+        errors.add(e);
 
-	}
+    }
 
-	/**
-	 * Checks if the given platform node belongs to any way
-	 */
-	protected void performPlatformPartOfWayTest() {
+    /**
+     * Checks if the given platform node belongs to any way
+     */
+    protected void performPlatformPartOfWayTest() {
 
-		List<OsmPrimitive> referrers = node.getReferrers();
+        List<OsmPrimitive> referrers = node.getReferrers();
 
-		for (OsmPrimitive referrer : referrers) {
-			List<Node> primitives = new ArrayList<>(1);
-			primitives.add(node);
-			if (referrer.getType().equals(OsmPrimitiveType.WAY)) {
-				Way referringWay = (Way) referrer;
-				if (RouteUtils.isWaySuitableForPublicTransport(referringWay)) {
-					Builder builder = TestError.builder(this.test, Severity.WARNING, PTAssistantValidatorTest.ERROR_CODE_PLATFORM_PART_OF_HIGHWAY);
-					builder.message(tr("PT: Platform should not be part of a way"));
-					builder.primitives(primitives);
-					TestError e = builder.build();
-					errors.add(e);
-					return;
-				}
-			}
-		}
-	}
+        for (OsmPrimitive referrer : referrers) {
+            List<Node> primitives = new ArrayList<>(1);
+            primitives.add(node);
+            if (referrer.getType().equals(OsmPrimitiveType.WAY)) {
+                Way referringWay = (Way) referrer;
+                if (RouteUtils.isWaySuitableForPublicTransport(referringWay)) {
+                    Builder builder = TestError.builder(this.test, Severity.WARNING, PTAssistantValidatorTest.ERROR_CODE_PLATFORM_PART_OF_HIGHWAY);
+                    builder.message(tr("PT: Platform should not be part of a way"));
+                    builder.primitives(primitives);
+                    TestError e = builder.build();
+                    errors.add(e);
+                    return;
+                }
+            }
+        }
+    }
 
-	/**
-	 * Checks if the given stop_position node belongs to any stop_area relation
-	 * 
-	 * @author xamanu
-	 */
-	protected void performNodePartOfStopAreaTest() {
+    /**
+     * Checks if the given stop_position node belongs to any stop_area relation
+     *
+     * @author xamanu
+     */
+    protected void performNodePartOfStopAreaTest() {
 
-		if (!StopUtils.verifyIfMemberOfStopArea(node)) {
+        if (!StopUtils.verifyIfMemberOfStopArea(node)) {
 
-			List<OsmPrimitive> primitives = new ArrayList<>(1);
-			primitives.add(node);
-			Builder builder = TestError.builder(this.test, Severity.WARNING, PTAssistantValidatorTest.ERROR_CODE_NOT_PART_OF_STOP_AREA);
-			builder.message(tr("PT: Stop position or platform is not part of a stop area relation"));
-			builder.primitives(primitives);
-			TestError e = builder.build();
-			errors.add(e);
-		}
-	}
+            List<OsmPrimitive> primitives = new ArrayList<>(1);
+            primitives.add(node);
+            Builder builder = TestError.builder(this.test, Severity.WARNING, PTAssistantValidatorTest.ERROR_CODE_NOT_PART_OF_STOP_AREA);
+            builder.message(tr("PT: Stop position or platform is not part of a stop area relation"));
+            builder.primitives(primitives);
+            TestError e = builder.build();
+            errors.add(e);
+        }
+    }
 
-	/**
-	 * Fixes errors: solitary stop position and platform which is part of a way.
-	 * Asks the user first.
-	 *
-	 * @param testError
-	 *            test error
-	 * @return fix command
-	 */
-	protected static Command fixError(TestError testError) {
+    /**
+     * Fixes errors: solitary stop position and platform which is part of a way.
+     * Asks the user first.
+     *
+     * @param testError
+     *            test error
+     * @return fix command
+     */
+    protected static Command fixError(TestError testError) {
 
-		if (testError.getCode() != PTAssistantValidatorTest.ERROR_CODE_SOLITARY_STOP_POSITION
-				&& testError.getCode() != PTAssistantValidatorTest.ERROR_CODE_PLATFORM_PART_OF_HIGHWAY) {
-			return null;
-		}
+        if (testError.getCode() != PTAssistantValidatorTest.ERROR_CODE_SOLITARY_STOP_POSITION
+                && testError.getCode() != PTAssistantValidatorTest.ERROR_CODE_PLATFORM_PART_OF_HIGHWAY) {
+            return null;
+        }
 
-		Node problematicNode = (Node) testError.getPrimitives().iterator().next();
+        Node problematicNode = (Node) testError.getPrimitives().iterator().next();
 
-		final int[] userSelection = { JOptionPane.YES_OPTION };
-		final TestError errorParameter = testError;
-		if (SwingUtilities.isEventDispatchThread()) {
+        final int[] userSelection = { JOptionPane.YES_OPTION };
+        final TestError errorParameter = testError;
+        if (SwingUtilities.isEventDispatchThread()) {
 
-			userSelection[0] = showFixNodeTagDialog(errorParameter);
+            userSelection[0] = showFixNodeTagDialog(errorParameter);
 
-		} else {
+        } else {
 
-			try {
-				SwingUtilities.invokeAndWait(new Runnable() {
-					@Override
-					public void run() {
-						userSelection[0] = showFixNodeTagDialog(errorParameter);
-					}
-				});
-			} catch (InvocationTargetException | InterruptedException e) {
-				e.printStackTrace();
-				return null;
-			}
-		}
+            try {
+                SwingUtilities.invokeAndWait(new Runnable() {
+                    @Override
+                    public void run() {
+                        userSelection[0] = showFixNodeTagDialog(errorParameter);
+                    }
+                });
+            } catch (InvocationTargetException | InterruptedException e) {
+                e.printStackTrace();
+                return null;
+            }
+        }
 
-		if (userSelection[0] == JOptionPane.YES_OPTION) {
+        if (userSelection[0] == JOptionPane.YES_OPTION) {
 
-			Node modifiedNode = new Node(problematicNode);
-			if (testError.getCode() == PTAssistantValidatorTest.ERROR_CODE_SOLITARY_STOP_POSITION) {
-				modifiedNode.put("public_transport", "platform");
-				ChangeCommand command = new ChangeCommand(problematicNode, modifiedNode);
-				return command;
-			} else {
-				modifiedNode.put("public_transport", "stop_position");
-				ChangeCommand command = new ChangeCommand(problematicNode, modifiedNode);
-				return command;
-			}
-		}
+            Node modifiedNode = new Node(problematicNode);
+            if (testError.getCode() == PTAssistantValidatorTest.ERROR_CODE_SOLITARY_STOP_POSITION) {
+                modifiedNode.put("public_transport", "platform");
+                ChangeCommand command = new ChangeCommand(problematicNode, modifiedNode);
+                return command;
+            } else {
+                modifiedNode.put("public_transport", "stop_position");
+                ChangeCommand command = new ChangeCommand(problematicNode, modifiedNode);
+                return command;
+            }
+        }
 
-		return null;
+        return null;
 
-	}
+    }
 
-	private static int showFixNodeTagDialog(TestError e) {
-		Node problematicNode = (Node) e.getPrimitives().iterator().next();
-		// Main.map.mapView.zoomTo(problematicNode.getCoor());
-		// zoom to problem:
-		Collection<OsmPrimitive> primitives = new ArrayList<>(1);
-		primitives.add(problematicNode);
-		AutoScaleAction.zoomTo(primitives);
+    private static int showFixNodeTagDialog(TestError e) {
+        Node problematicNode = (Node) e.getPrimitives().iterator().next();
+        // Main.map.mapView.zoomTo(problematicNode.getCoor());
+        // zoom to problem:
+        Collection<OsmPrimitive> primitives = new ArrayList<>(1);
+        primitives.add(problematicNode);
+        AutoScaleAction.zoomTo(primitives);
 
-		String[] options = { tr("Yes"), tr("No") };
-		String message;
-		if (e.getCode() == PTAssistantValidatorTest.ERROR_CODE_SOLITARY_STOP_POSITION) {
-			message = "Do you want to change the tag public_transport=stop_position to public_transport=platform?";
-		} else {
-			message = "Do you want to change the tag public_transport=platform to public_transport=stop_position?";
-		}
-		return JOptionPane.showOptionDialog(null, message, tr("PT_Assistant Message"), JOptionPane.YES_NO_OPTION,
-				JOptionPane.QUESTION_MESSAGE, null, options, 0);
-	}
+        String[] options = { tr("Yes"), tr("No") };
+        String message;
+        if (e.getCode() == PTAssistantValidatorTest.ERROR_CODE_SOLITARY_STOP_POSITION) {
+            message = "Do you want to change the tag public_transport=stop_position to public_transport=platform?";
+        } else {
+            message = "Do you want to change the tag public_transport=platform to public_transport=stop_position?";
+        }
+        return JOptionPane.showOptionDialog(null, message, tr("PT_Assistant Message"), JOptionPane.YES_NO_OPTION,
+                JOptionPane.QUESTION_MESSAGE, null, options, 0);
+    }
 
 }
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/PTAssistantValidatorTest.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/PTAssistantValidatorTest.java	(revision 33416)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/PTAssistantValidatorTest.java	(revision 33417)
@@ -44,549 +44,549 @@
 public class PTAssistantValidatorTest extends Test {
 
-	public static final int ERROR_CODE_SORTING = 3711;
-	public static final int ERROR_CODE_PARTIAL_SORTING = 3712;
-	public static final int ERROR_CODE_ROAD_TYPE = 3721;
-	public static final int ERROR_CODE_CONSTRUCTION = 3722;
-	public static final int ERROR_CODE_DIRECTION = 3731;
-	public static final int ERROR_CODE_END_STOP = 3741;
-	public static final int ERROR_CODE_SPLIT_WAY = 3742;
-	public static final int ERROR_CODE_RELATION_MEMBER_ROLES = 3743;
-	public static final int ERROR_CODE_SOLITARY_STOP_POSITION = 3751;
-	public static final int ERROR_CODE_PLATFORM_PART_OF_HIGHWAY = 3752;
-	public static final int ERROR_CODE_STOP_NOT_SERVED = 3753;
-	public static final int ERROR_CODE_STOP_BY_STOP = 3754;
-	public static final int ERROR_CODE_NOT_PART_OF_STOP_AREA = 3761;
-	public static final int ERROR_CODE_STOP_AREA_NO_STOPS = 3762;
-	public static final int ERROR_CODE_STOP_AREA_NO_PLATFORM = 3763;
-	public static final int ERROR_CODE_STOP_AREA_COMPARE_RELATIONS = 3764;
-
-	public PTAssistantValidatorTest() {
-		super(tr("Public Transport Assistant tests"),
-				tr("Check if route relations are compatible with public transport version 2"));
-
-		DataSet.addSelectionListener(PTAssistantLayerManager.PTLM);
-
-	}
-
-	@Override
-	public void visit(Node n) {
-
-		if (n.isIncomplete()) {
-			return;
-		}
-
-		NodeChecker nodeChecker = new NodeChecker(n, this);
-
-		// select only stop_positions
-		if (n.hasTag("public_transport", "stop_position")) {
-
-			// check if stop positions are on a way:
-			nodeChecker.performSolitaryStopPositionTest();
-
-			if (Main.pref.getBoolean("pt_assistant.stop-area-tests", false) == true) {
-				// check if stop positions are in any stop_area relation:
-				nodeChecker.performNodePartOfStopAreaTest();
-			}
-
-		}
-
-		// select only platforms
-		if (n.hasTag("public_transport", "platform")) {
-
-			// check that platforms are not part of any way:
-			nodeChecker.performPlatformPartOfWayTest();
-
-			if (Main.pref.getBoolean("pt_assistant.stop-area-tests", false) == true) {
-				// check if platforms are in any stop_area relation:
-				nodeChecker.performNodePartOfStopAreaTest();
-			}
-
-		}
-
-		this.errors.addAll(nodeChecker.getErrors());
-
-	}
-
-	@Override
-	public void visit(Relation r) {
-
-		// Download incomplete members. If the download does not work, return
-		// and do not do any testing.
-		if (r.hasIncompleteMembers()) {
-
-			boolean downloadSuccessful = this.downloadIncompleteMembers();
-			if (!downloadSuccessful) {
-				return;
-			}
-		}
-
-		if (r.hasIncompleteMembers()) {
-			return;
-		}
-
-		// Do some testing on stop area relations
-		if (Main.pref.getBoolean("pt_assistant.stop-area-tests", false) == true && StopUtils.isStopArea(r)) {
-
-			StopChecker stopChecker = new StopChecker(r, this);
-
-			// Check if stop area relation has one stop position.
-			stopChecker.performStopAreaStopPositionTest();
-
-			// Check if stop area relation has one platform.
-			stopChecker.performStopAreaPlatformTest();
-
-			// Check if stop position(s) belong the same route relation as
-			// related platform(s)
-			stopChecker.performStopAreaRelationsTest();
-
-			// Attach thrown errors
-			this.errors.addAll(stopChecker.getErrors());
-		}
-
-		if (!RouteUtils.isVersionTwoPTRoute(r)) {
-			return;
-		}
-
-		// Check individual ways using the oneway direction test and the road
-		// type test:
-		WayChecker wayChecker = new WayChecker(r, this);
-		wayChecker.performDirectionTest();
-		wayChecker.performRoadTypeTest();
-		this.errors.addAll(wayChecker.getErrors());
-
-		proceedWithSorting(r);
-
-		// This allows to modify the route before the sorting and
-		// SegmentChecker are carried out:
-		// if (this.errors.isEmpty()) {
-		// proceedWithSorting(r);
-		// } else {
-		// this.proceedAfterWayCheckerErrors(r);
-		// }
-
-	}
-
-	/**
-	 * Downloads incomplete relation members in an extra thread (user input
-	 * required)
-	 *
-	 * @return true if successful, false if not successful
-	 */
-	private boolean downloadIncompleteMembers() {
-
-		final int[] userSelection = { 0 };
-
-		try {
-
-			if (SwingUtilities.isEventDispatchThread()) {
-
-				userSelection[0] = showIncompleteMembersDownloadDialog();
-
-			} else {
-
-				SwingUtilities.invokeAndWait(new Runnable() {
-					@Override
-					public void run() {
-						try {
-							userSelection[0] = showIncompleteMembersDownloadDialog();
-						} catch (InterruptedException e) {
-							e.printStackTrace();
-						}
-
-					}
-				});
-
-			}
-
-		} catch (InterruptedException | InvocationTargetException e) {
-			return false;
-		}
-
-		if (userSelection[0] == JOptionPane.YES_OPTION) {
-
-			Thread t = new IncompleteMembersDownloadThread();
-			t.start();
-			synchronized (t) {
-				try {
-					t.wait();
-				} catch (InterruptedException e) {
-					return false;
-				}
-			}
-
-		}
-
-		return true;
-
-	}
-
-	/**
-	 * Shows the dialog asking the user about an incomplete member download
-	 *
-	 * @return user's selection
-	 * @throws InterruptedException
-	 *             if interrupted
-	 */
-	private int showIncompleteMembersDownloadDialog() throws InterruptedException {
-
-		if (Main.pref.getBoolean("pt_assistant.download-incomplete", false) == true) {
-			return JOptionPane.YES_OPTION;
-		}
-
-		if (Main.pref.getBoolean("pt_assistant.download-incomplete", false) == false) {
-			return JOptionPane.NO_OPTION;
-		}
-
-		IncompleteMembersDownloadDialog incompleteMembersDownloadDialog = new IncompleteMembersDownloadDialog();
-		return incompleteMembersDownloadDialog.getUserSelection();
-
-	}
-
-	/**
-	 * Gets user input after errors were detected by WayChecker. Although this
-	 * method is not used in the current implementation, it can be used to fix
-	 * errors from the previous testing stage and modify the route before the
-	 * second stage of testing is carried out.
-	 */
-	@SuppressWarnings("unused")
-	private void proceedAfterWayCheckerErrors(Relation r) {
-
-		// count errors of each type:
-		int numberOfDirectionErrors = 0;
-		int numberOfRoadTypeErrors = 0;
-		for (TestError e : this.errors) {
-			if (e.getCode() == ERROR_CODE_DIRECTION) {
-				numberOfDirectionErrors++;
-			}
-			if (e.getCode() == ERROR_CODE_ROAD_TYPE) {
-				numberOfRoadTypeErrors++;
-			}
-		}
-
-		final int[] userInput = { 0 };
-		final long idParameter = r.getId();
-		final int directionErrorParameter = numberOfDirectionErrors;
-		final int roadTypeErrorParameter = numberOfRoadTypeErrors;
-
-		if (SwingUtilities.isEventDispatchThread()) {
-
-			userInput[0] = showProceedDialog(idParameter, directionErrorParameter, roadTypeErrorParameter);
-
-		} else {
-
-			try {
-				SwingUtilities.invokeAndWait(new Runnable() {
-					@Override
-					public void run() {
-						userInput[0] = showProceedDialog(idParameter, directionErrorParameter, roadTypeErrorParameter);
-
-					}
-				});
-			} catch (InvocationTargetException | InterruptedException e1) {
-				e1.printStackTrace();
-			}
-
-		}
-
-		if (userInput[0] == 0) {
-			this.fixErrorFromPlugin(this.errors);
-			proceedWithSorting(r);
-			return;
-		}
-
-		if (userInput[0] == 1) {
-			JOptionPane.showMessageDialog(null, "This is not implemented yet!");
-			return;
-		}
-
-		if (userInput[0] == 2) {
-			proceedWithSorting(r);
-		}
-
-		// if userInput==-1 (i.e. no input), do nothing and stop testing of the
-		// route.
-
-	}
-
-	private int showProceedDialog(long id, int numberOfDirectionErrors, int numberOfRoadTypeErrors) {
-
-		if (numberOfDirectionErrors == 0 && numberOfRoadTypeErrors == 0) {
-			return 2;
-		}
-
-		if (Main.pref.getBoolean("pt_assistant.proceed-without-fix", true) == false) {
-			return 0;
-		}
-
-		if (Main.pref.getBoolean("pt_assistant.proceed-without-fix", true) == true) {
-			return 2;
-		}
-
-		ProceedDialog proceedDialog = new ProceedDialog(id, numberOfDirectionErrors, numberOfRoadTypeErrors);
-		return proceedDialog.getUserSelection();
-
-	}
-
-	/**
-	 * Carries out the second stage of the testing: sorting
-	 *
-	 * @param r
-	 *            relation
-	 */
-	private void proceedWithSorting(Relation r) {
-
-		// Check if the relation is correct, or only has a wrong sorting order:
-		RouteChecker routeChecker = new RouteChecker(r, this);
-		routeChecker.performSortingTest();
-		List<TestError> routeCheckerErrors = routeChecker.getErrors();
-
-		/*- At this point, there are 3 variants:
-		 *
-		 * 1) There are no errors => route is correct
-		 * 2) There is only a sorting error (can only be 1), but otherwise
-		 * correct.
-		 * 3) There are some other errors/gaps that cannot be fixed by
-		 * sorting => start further test (stop-by-stop)
-		 *
-		 * */
-
-		if (!routeCheckerErrors.isEmpty()) {
-			// Variant 2
-			// If there is only the sorting error, add it
-			this.errors.addAll(routeChecker.getErrors());
-		}
-
-		// if (!routeChecker.getHasGap()) {
-		// // Variant 1
-		// storeCorrectRouteSegments(r);
-		// }
-
-		// Variant 3:
-		proceedAfterSorting(r);
-
-	}
-
-	/**
-	 * Carries out the stop-by-stop testing which includes building the route
-	 * data model.
-	 *
-	 * @param r
-	 *            route relation
-	 */
-	private void proceedAfterSorting(Relation r) {
-
-		SegmentChecker segmentChecker = new SegmentChecker(r, this);
-
-		// Check if the creation of the route data model in the segment checker
-		// worked. If it did not, it means the roles in the route relation do
-		// not match the tags of the route members.
-		if (!segmentChecker.getErrors().isEmpty()) {
-			this.errors.addAll(segmentChecker.getErrors());
-		}
-
-		segmentChecker.performFirstStopTest();
-		segmentChecker.performLastStopTest();
-		segmentChecker.performStopNotServedTest();
-
-		boolean sortingErrorFound = false;
-		for (TestError error : this.errors) {
-			if (error.getCode() == ERROR_CODE_SORTING
-					|| error.getCode() == ERROR_CODE_PARTIAL_SORTING) {
-				sortingErrorFound = true;
-				break;
-			}
-		}
-		if (!sortingErrorFound) {
-			segmentChecker.performStopByStopTest();
-			segmentChecker.findFixes();
-		}
-
-		for (TestError error : segmentChecker.getErrors()) {
-			if (error.getCode() != PTAssistantValidatorTest.ERROR_CODE_RELATION_MEMBER_ROLES) {
-				this.errors.add(error);
-			}
-		}
-	}
-
-	@Override
-	public void startTest(ProgressMonitor progressMonitor) {
-		super.startTest(progressMonitor);
-
-		// reset the static collections in SegmentChecker:
-		SegmentChecker.reset();
-	}
-
-	/**
-	 * Method is called after all primitives has been visited, overrides the
-	 * method of the superclass.
-	 */
-	@Override
-	public void endTest() {
-
-		// modify the error messages for the stop-by-stop test:
-		SegmentChecker.modifyStopByStopErrorMessages();
-
-		// add the stop-by-stop errors with modified messages:
-		for (Entry<Builder, PTRouteSegment> entry : SegmentChecker.wrongSegmentBuilders.entrySet()) {
-			TestError error = entry.getKey().build();
-			SegmentChecker.wrongSegments.put(error, entry.getValue());
-			this.errors.add(error);
-		}
-
-		super.endTest();
-
-	}
-
-	/**
-	 * Creates the PTRouteSegments of a route that has been found correct and
-	 * stores them in the list of correct route segments
-	 *
-	 * @param r
-	 *            route relation
-	 */
-	@SuppressWarnings("unused")
-	private void storeCorrectRouteSegments(Relation r) {
-		PTRouteDataManager manager = new PTRouteDataManager(r);
-		StopToWayAssigner assigner = new StopToWayAssigner(manager.getPTWays());
-		if (manager.getPTStops().size() > 1) {
-			for (int i = 1; i < manager.getPTStops().size(); i++) {
-				PTStop segmentStartStop = manager.getPTStops().get(i - 1);
-				PTStop segmentEndStop = manager.getPTStops().get(i);
-				Way segmentStartWay = assigner.get(segmentStartStop);
-				Way segmentEndWay = assigner.get(segmentEndStop);
-				List<PTWay> waysBetweenStops = manager.getPTWaysBetween(segmentStartWay, segmentEndWay);
-				PTRouteSegment routeSegment = new PTRouteSegment(segmentStartStop, segmentEndStop, waysBetweenStops, r);
-				SegmentChecker.addCorrectSegment(routeSegment);
-			}
-		}
-	}
-
-	/**
-	 * Checks if the test error is fixable
-	 */
-	@Override
-	public boolean isFixable(TestError testError) {
-		if (testError.getCode() == ERROR_CODE_DIRECTION
-				|| testError.getCode() == ERROR_CODE_ROAD_TYPE
-				|| testError.getCode() == ERROR_CODE_CONSTRUCTION
-				|| testError.getCode() == ERROR_CODE_SORTING
-				|| testError.getCode() == ERROR_CODE_PARTIAL_SORTING
-				|| testError.getCode() == ERROR_CODE_END_STOP
-				|| testError.getCode() == ERROR_CODE_PLATFORM_PART_OF_HIGHWAY) {
-			return true;
-		}
-
-		if (testError.getCode() == ERROR_CODE_STOP_BY_STOP && SegmentChecker.isFixable(testError)) {
-			return true;
-		}
-
-		return false;
-	}
-
-	/**
-	 * Fixes the given error
-	 */
-	@Override
-	public Command fixError(TestError testError) {
-
-		// repaint the relation in the pt_assistant layer:
-		if (testError.getPrimitives().iterator().next().getType().equals(OsmPrimitiveType.RELATION)) {
-			Relation relationToBeFixed = (Relation) testError.getPrimitives().iterator().next();
-			PTAssistantLayerManager.PTLM.getLayer().repaint(relationToBeFixed);
-		}
-
-		// reset the last fix:
-		PTAssistantPlugin.setLastFix(null);
-
-		List<Command> commands = new ArrayList<>();
-
-		if (testError.getCode() == ERROR_CODE_ROAD_TYPE
-				|| testError.getCode() == ERROR_CODE_CONSTRUCTION
-				|| testError.getCode() == ERROR_CODE_DIRECTION
-				|| testError.getCode() == ERROR_CODE_END_STOP) {
-			commands.add(WayChecker.fixErrorByZooming(testError));
-		}
-
-		if (testError.getCode() == ERROR_CODE_SORTING
-				|| testError.getCode() == ERROR_CODE_PARTIAL_SORTING) {
-			commands.add(RouteChecker.fixSortingError(testError));
-		}
-
-		if (testError.getCode() == ERROR_CODE_SOLITARY_STOP_POSITION
-				|| testError.getCode() == ERROR_CODE_PLATFORM_PART_OF_HIGHWAY) {
-			commands.add(NodeChecker.fixError(testError));
-		}
-
-		if (testError.getCode() == ERROR_CODE_STOP_BY_STOP) {
-			commands.add(SegmentChecker.fixError(testError));
-			// make sure the primitives of this testError are selected:
-			Collection<OsmPrimitive> primitivesToSelect = new ArrayList<>();
-			for (Object obj : testError.getPrimitives()) {
-				primitivesToSelect.add((OsmPrimitive) obj);
-			}
-			SelectCommand selectCommand = new SelectCommand(primitivesToSelect);
-			SwingUtilities.invokeLater(new Runnable() {
-				@Override
-				public void run() {
-					selectCommand.executeCommand();
-				}
-			});
-		}
-
-		if (commands.isEmpty()) {
-			return null;
-		}
-
-		if (commands.size() == 1) {
-			return commands.get(0);
-		}
-
-		return new SequenceCommand(tr("Fix error"), commands);
-	}
-
-	/**
-	 * This method is the counterpart of the fixError(TestError testError)
-	 * method. The fixError method is invoked from the core validator (e.g. when
-	 * user presses the "Fix" button in the validator). This method is invoken
-	 * when the fix is initiated from within the plugin (e.g. automated fixes).
-	 */
-	private void fixErrorFromPlugin(List<TestError> testErrors) {
-
-		// run fix task asynchronously
-		FixTask fixTask = new FixTask(testErrors);
-
-		Thread t = new Thread(fixTask);
-		t.start();
-		try {
-			t.join();
-			errors.removeAll(testErrors);
-
-		} catch (InterruptedException e) {
-			JOptionPane.showMessageDialog(null, "Error occurred during fixing");
-		}
-
-	}
-
-	public void addFixVariants(List<List<PTWay>> fixVariants) {
-		PTAssistantLayerManager.PTLM.getLayer().addFixVariants(fixVariants);
-	}
-
-	public void clearFixVariants() {
-		PTAssistantLayerManager.PTLM.getLayer().clearFixVariants();
-	}
-
-	public List<PTWay> getFixVariant(Character c) {
-		return PTAssistantLayerManager.PTLM.getLayer().getFixVariant(c);
-	}
-
-	@SuppressWarnings("unused")
-	private void performDummyTest(Relation r) {
-		List<Relation> primitives = new ArrayList<>(1);
-		primitives.add(r);
-		Builder builder = TestError.builder(this, Severity.WARNING, ERROR_CODE_DIRECTION);
-		builder.message(tr("PT: dummy test warning"));
-		builder.primitives(primitives);
-		errors.add(builder.build());
-	}
+    public static final int ERROR_CODE_SORTING = 3711;
+    public static final int ERROR_CODE_PARTIAL_SORTING = 3712;
+    public static final int ERROR_CODE_ROAD_TYPE = 3721;
+    public static final int ERROR_CODE_CONSTRUCTION = 3722;
+    public static final int ERROR_CODE_DIRECTION = 3731;
+    public static final int ERROR_CODE_END_STOP = 3741;
+    public static final int ERROR_CODE_SPLIT_WAY = 3742;
+    public static final int ERROR_CODE_RELATION_MEMBER_ROLES = 3743;
+    public static final int ERROR_CODE_SOLITARY_STOP_POSITION = 3751;
+    public static final int ERROR_CODE_PLATFORM_PART_OF_HIGHWAY = 3752;
+    public static final int ERROR_CODE_STOP_NOT_SERVED = 3753;
+    public static final int ERROR_CODE_STOP_BY_STOP = 3754;
+    public static final int ERROR_CODE_NOT_PART_OF_STOP_AREA = 3761;
+    public static final int ERROR_CODE_STOP_AREA_NO_STOPS = 3762;
+    public static final int ERROR_CODE_STOP_AREA_NO_PLATFORM = 3763;
+    public static final int ERROR_CODE_STOP_AREA_COMPARE_RELATIONS = 3764;
+
+    public PTAssistantValidatorTest() {
+        super(tr("Public Transport Assistant tests"),
+                tr("Check if route relations are compatible with public transport version 2"));
+
+        DataSet.addSelectionListener(PTAssistantLayerManager.PTLM);
+
+    }
+
+    @Override
+    public void visit(Node n) {
+
+        if (n.isIncomplete()) {
+            return;
+        }
+
+        NodeChecker nodeChecker = new NodeChecker(n, this);
+
+        // select only stop_positions
+        if (n.hasTag("public_transport", "stop_position")) {
+
+            // check if stop positions are on a way:
+            nodeChecker.performSolitaryStopPositionTest();
+
+            if (Main.pref.getBoolean("pt_assistant.stop-area-tests", false) == true) {
+                // check if stop positions are in any stop_area relation:
+                nodeChecker.performNodePartOfStopAreaTest();
+            }
+
+        }
+
+        // select only platforms
+        if (n.hasTag("public_transport", "platform")) {
+
+            // check that platforms are not part of any way:
+            nodeChecker.performPlatformPartOfWayTest();
+
+            if (Main.pref.getBoolean("pt_assistant.stop-area-tests", false) == true) {
+                // check if platforms are in any stop_area relation:
+                nodeChecker.performNodePartOfStopAreaTest();
+            }
+
+        }
+
+        this.errors.addAll(nodeChecker.getErrors());
+
+    }
+
+    @Override
+    public void visit(Relation r) {
+
+        // Download incomplete members. If the download does not work, return
+        // and do not do any testing.
+        if (r.hasIncompleteMembers()) {
+
+            boolean downloadSuccessful = this.downloadIncompleteMembers();
+            if (!downloadSuccessful) {
+                return;
+            }
+        }
+
+        if (r.hasIncompleteMembers()) {
+            return;
+        }
+
+        // Do some testing on stop area relations
+        if (Main.pref.getBoolean("pt_assistant.stop-area-tests", false) == true && StopUtils.isStopArea(r)) {
+
+            StopChecker stopChecker = new StopChecker(r, this);
+
+            // Check if stop area relation has one stop position.
+            stopChecker.performStopAreaStopPositionTest();
+
+            // Check if stop area relation has one platform.
+            stopChecker.performStopAreaPlatformTest();
+
+            // Check if stop position(s) belong the same route relation as
+            // related platform(s)
+            stopChecker.performStopAreaRelationsTest();
+
+            // Attach thrown errors
+            this.errors.addAll(stopChecker.getErrors());
+        }
+
+        if (!RouteUtils.isVersionTwoPTRoute(r)) {
+            return;
+        }
+
+        // Check individual ways using the oneway direction test and the road
+        // type test:
+        WayChecker wayChecker = new WayChecker(r, this);
+        wayChecker.performDirectionTest();
+        wayChecker.performRoadTypeTest();
+        this.errors.addAll(wayChecker.getErrors());
+
+        proceedWithSorting(r);
+
+        // This allows to modify the route before the sorting and
+        // SegmentChecker are carried out:
+        // if (this.errors.isEmpty()) {
+        // proceedWithSorting(r);
+        // } else {
+        // this.proceedAfterWayCheckerErrors(r);
+        // }
+
+    }
+
+    /**
+     * Downloads incomplete relation members in an extra thread (user input
+     * required)
+     *
+     * @return true if successful, false if not successful
+     */
+    private boolean downloadIncompleteMembers() {
+
+        final int[] userSelection = { 0 };
+
+        try {
+
+            if (SwingUtilities.isEventDispatchThread()) {
+
+                userSelection[0] = showIncompleteMembersDownloadDialog();
+
+            } else {
+
+                SwingUtilities.invokeAndWait(new Runnable() {
+                    @Override
+                    public void run() {
+                        try {
+                            userSelection[0] = showIncompleteMembersDownloadDialog();
+                        } catch (InterruptedException e) {
+                            e.printStackTrace();
+                        }
+
+                    }
+                });
+
+            }
+
+        } catch (InterruptedException | InvocationTargetException e) {
+            return false;
+        }
+
+        if (userSelection[0] == JOptionPane.YES_OPTION) {
+
+            Thread t = new IncompleteMembersDownloadThread();
+            t.start();
+            synchronized (t) {
+                try {
+                    t.wait();
+                } catch (InterruptedException e) {
+                    return false;
+                }
+            }
+
+        }
+
+        return true;
+
+    }
+
+    /**
+     * Shows the dialog asking the user about an incomplete member download
+     *
+     * @return user's selection
+     * @throws InterruptedException
+     *             if interrupted
+     */
+    private int showIncompleteMembersDownloadDialog() throws InterruptedException {
+
+        if (Main.pref.getBoolean("pt_assistant.download-incomplete", false) == true) {
+            return JOptionPane.YES_OPTION;
+        }
+
+        if (Main.pref.getBoolean("pt_assistant.download-incomplete", false) == false) {
+            return JOptionPane.NO_OPTION;
+        }
+
+        IncompleteMembersDownloadDialog incompleteMembersDownloadDialog = new IncompleteMembersDownloadDialog();
+        return incompleteMembersDownloadDialog.getUserSelection();
+
+    }
+
+    /**
+     * Gets user input after errors were detected by WayChecker. Although this
+     * method is not used in the current implementation, it can be used to fix
+     * errors from the previous testing stage and modify the route before the
+     * second stage of testing is carried out.
+     */
+    @SuppressWarnings("unused")
+    private void proceedAfterWayCheckerErrors(Relation r) {
+
+        // count errors of each type:
+        int numberOfDirectionErrors = 0;
+        int numberOfRoadTypeErrors = 0;
+        for (TestError e : this.errors) {
+            if (e.getCode() == ERROR_CODE_DIRECTION) {
+                numberOfDirectionErrors++;
+            }
+            if (e.getCode() == ERROR_CODE_ROAD_TYPE) {
+                numberOfRoadTypeErrors++;
+            }
+        }
+
+        final int[] userInput = { 0 };
+        final long idParameter = r.getId();
+        final int directionErrorParameter = numberOfDirectionErrors;
+        final int roadTypeErrorParameter = numberOfRoadTypeErrors;
+
+        if (SwingUtilities.isEventDispatchThread()) {
+
+            userInput[0] = showProceedDialog(idParameter, directionErrorParameter, roadTypeErrorParameter);
+
+        } else {
+
+            try {
+                SwingUtilities.invokeAndWait(new Runnable() {
+                    @Override
+                    public void run() {
+                        userInput[0] = showProceedDialog(idParameter, directionErrorParameter, roadTypeErrorParameter);
+
+                    }
+                });
+            } catch (InvocationTargetException | InterruptedException e1) {
+                e1.printStackTrace();
+            }
+
+        }
+
+        if (userInput[0] == 0) {
+            this.fixErrorFromPlugin(this.errors);
+            proceedWithSorting(r);
+            return;
+        }
+
+        if (userInput[0] == 1) {
+            JOptionPane.showMessageDialog(null, "This is not implemented yet!");
+            return;
+        }
+
+        if (userInput[0] == 2) {
+            proceedWithSorting(r);
+        }
+
+        // if userInput==-1 (i.e. no input), do nothing and stop testing of the
+        // route.
+
+    }
+
+    private int showProceedDialog(long id, int numberOfDirectionErrors, int numberOfRoadTypeErrors) {
+
+        if (numberOfDirectionErrors == 0 && numberOfRoadTypeErrors == 0) {
+            return 2;
+        }
+
+        if (Main.pref.getBoolean("pt_assistant.proceed-without-fix", true) == false) {
+            return 0;
+        }
+
+        if (Main.pref.getBoolean("pt_assistant.proceed-without-fix", true) == true) {
+            return 2;
+        }
+
+        ProceedDialog proceedDialog = new ProceedDialog(id, numberOfDirectionErrors, numberOfRoadTypeErrors);
+        return proceedDialog.getUserSelection();
+
+    }
+
+    /**
+     * Carries out the second stage of the testing: sorting
+     *
+     * @param r
+     *            relation
+     */
+    private void proceedWithSorting(Relation r) {
+
+        // Check if the relation is correct, or only has a wrong sorting order:
+        RouteChecker routeChecker = new RouteChecker(r, this);
+        routeChecker.performSortingTest();
+        List<TestError> routeCheckerErrors = routeChecker.getErrors();
+
+        /*- At this point, there are 3 variants:
+         *
+         * 1) There are no errors => route is correct
+         * 2) There is only a sorting error (can only be 1), but otherwise
+         * correct.
+         * 3) There are some other errors/gaps that cannot be fixed by
+         * sorting => start further test (stop-by-stop)
+         *
+         * */
+
+        if (!routeCheckerErrors.isEmpty()) {
+            // Variant 2
+            // If there is only the sorting error, add it
+            this.errors.addAll(routeChecker.getErrors());
+        }
+
+        // if (!routeChecker.getHasGap()) {
+        // // Variant 1
+        // storeCorrectRouteSegments(r);
+        // }
+
+        // Variant 3:
+        proceedAfterSorting(r);
+
+    }
+
+    /**
+     * Carries out the stop-by-stop testing which includes building the route
+     * data model.
+     *
+     * @param r
+     *            route relation
+     */
+    private void proceedAfterSorting(Relation r) {
+
+        SegmentChecker segmentChecker = new SegmentChecker(r, this);
+
+        // Check if the creation of the route data model in the segment checker
+        // worked. If it did not, it means the roles in the route relation do
+        // not match the tags of the route members.
+        if (!segmentChecker.getErrors().isEmpty()) {
+            this.errors.addAll(segmentChecker.getErrors());
+        }
+
+        segmentChecker.performFirstStopTest();
+        segmentChecker.performLastStopTest();
+        segmentChecker.performStopNotServedTest();
+
+        boolean sortingErrorFound = false;
+        for (TestError error : this.errors) {
+            if (error.getCode() == ERROR_CODE_SORTING
+                    || error.getCode() == ERROR_CODE_PARTIAL_SORTING) {
+                sortingErrorFound = true;
+                break;
+            }
+        }
+        if (!sortingErrorFound) {
+            segmentChecker.performStopByStopTest();
+            segmentChecker.findFixes();
+        }
+
+        for (TestError error : segmentChecker.getErrors()) {
+            if (error.getCode() != PTAssistantValidatorTest.ERROR_CODE_RELATION_MEMBER_ROLES) {
+                this.errors.add(error);
+            }
+        }
+    }
+
+    @Override
+    public void startTest(ProgressMonitor progressMonitor) {
+        super.startTest(progressMonitor);
+
+        // reset the static collections in SegmentChecker:
+        SegmentChecker.reset();
+    }
+
+    /**
+     * Method is called after all primitives has been visited, overrides the
+     * method of the superclass.
+     */
+    @Override
+    public void endTest() {
+
+        // modify the error messages for the stop-by-stop test:
+        SegmentChecker.modifyStopByStopErrorMessages();
+
+        // add the stop-by-stop errors with modified messages:
+        for (Entry<Builder, PTRouteSegment> entry : SegmentChecker.wrongSegmentBuilders.entrySet()) {
+            TestError error = entry.getKey().build();
+            SegmentChecker.wrongSegments.put(error, entry.getValue());
+            this.errors.add(error);
+        }
+
+        super.endTest();
+
+    }
+
+    /**
+     * Creates the PTRouteSegments of a route that has been found correct and
+     * stores them in the list of correct route segments
+     *
+     * @param r
+     *            route relation
+     */
+    @SuppressWarnings("unused")
+    private void storeCorrectRouteSegments(Relation r) {
+        PTRouteDataManager manager = new PTRouteDataManager(r);
+        StopToWayAssigner assigner = new StopToWayAssigner(manager.getPTWays());
+        if (manager.getPTStops().size() > 1) {
+            for (int i = 1; i < manager.getPTStops().size(); i++) {
+                PTStop segmentStartStop = manager.getPTStops().get(i - 1);
+                PTStop segmentEndStop = manager.getPTStops().get(i);
+                Way segmentStartWay = assigner.get(segmentStartStop);
+                Way segmentEndWay = assigner.get(segmentEndStop);
+                List<PTWay> waysBetweenStops = manager.getPTWaysBetween(segmentStartWay, segmentEndWay);
+                PTRouteSegment routeSegment = new PTRouteSegment(segmentStartStop, segmentEndStop, waysBetweenStops, r);
+                SegmentChecker.addCorrectSegment(routeSegment);
+            }
+        }
+    }
+
+    /**
+     * Checks if the test error is fixable
+     */
+    @Override
+    public boolean isFixable(TestError testError) {
+        if (testError.getCode() == ERROR_CODE_DIRECTION
+                || testError.getCode() == ERROR_CODE_ROAD_TYPE
+                || testError.getCode() == ERROR_CODE_CONSTRUCTION
+                || testError.getCode() == ERROR_CODE_SORTING
+                || testError.getCode() == ERROR_CODE_PARTIAL_SORTING
+                || testError.getCode() == ERROR_CODE_END_STOP
+                || testError.getCode() == ERROR_CODE_PLATFORM_PART_OF_HIGHWAY) {
+            return true;
+        }
+
+        if (testError.getCode() == ERROR_CODE_STOP_BY_STOP && SegmentChecker.isFixable(testError)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Fixes the given error
+     */
+    @Override
+    public Command fixError(TestError testError) {
+
+        // repaint the relation in the pt_assistant layer:
+        if (testError.getPrimitives().iterator().next().getType().equals(OsmPrimitiveType.RELATION)) {
+            Relation relationToBeFixed = (Relation) testError.getPrimitives().iterator().next();
+            PTAssistantLayerManager.PTLM.getLayer().repaint(relationToBeFixed);
+        }
+
+        // reset the last fix:
+        PTAssistantPlugin.setLastFix(null);
+
+        List<Command> commands = new ArrayList<>();
+
+        if (testError.getCode() == ERROR_CODE_ROAD_TYPE
+                || testError.getCode() == ERROR_CODE_CONSTRUCTION
+                || testError.getCode() == ERROR_CODE_DIRECTION
+                || testError.getCode() == ERROR_CODE_END_STOP) {
+            commands.add(WayChecker.fixErrorByZooming(testError));
+        }
+
+        if (testError.getCode() == ERROR_CODE_SORTING
+                || testError.getCode() == ERROR_CODE_PARTIAL_SORTING) {
+            commands.add(RouteChecker.fixSortingError(testError));
+        }
+
+        if (testError.getCode() == ERROR_CODE_SOLITARY_STOP_POSITION
+                || testError.getCode() == ERROR_CODE_PLATFORM_PART_OF_HIGHWAY) {
+            commands.add(NodeChecker.fixError(testError));
+        }
+
+        if (testError.getCode() == ERROR_CODE_STOP_BY_STOP) {
+            commands.add(SegmentChecker.fixError(testError));
+            // make sure the primitives of this testError are selected:
+            Collection<OsmPrimitive> primitivesToSelect = new ArrayList<>();
+            for (Object obj : testError.getPrimitives()) {
+                primitivesToSelect.add((OsmPrimitive) obj);
+            }
+            SelectCommand selectCommand = new SelectCommand(primitivesToSelect);
+            SwingUtilities.invokeLater(new Runnable() {
+                @Override
+                public void run() {
+                    selectCommand.executeCommand();
+                }
+            });
+        }
+
+        if (commands.isEmpty()) {
+            return null;
+        }
+
+        if (commands.size() == 1) {
+            return commands.get(0);
+        }
+
+        return new SequenceCommand(tr("Fix error"), commands);
+    }
+
+    /**
+     * This method is the counterpart of the fixError(TestError testError)
+     * method. The fixError method is invoked from the core validator (e.g. when
+     * user presses the "Fix" button in the validator). This method is invoken
+     * when the fix is initiated from within the plugin (e.g. automated fixes).
+     */
+    private void fixErrorFromPlugin(List<TestError> testErrors) {
+
+        // run fix task asynchronously
+        FixTask fixTask = new FixTask(testErrors);
+
+        Thread t = new Thread(fixTask);
+        t.start();
+        try {
+            t.join();
+            errors.removeAll(testErrors);
+
+        } catch (InterruptedException e) {
+            JOptionPane.showMessageDialog(null, "Error occurred during fixing");
+        }
+
+    }
+
+    public void addFixVariants(List<List<PTWay>> fixVariants) {
+        PTAssistantLayerManager.PTLM.getLayer().addFixVariants(fixVariants);
+    }
+
+    public void clearFixVariants() {
+        PTAssistantLayerManager.PTLM.getLayer().clearFixVariants();
+    }
+
+    public List<PTWay> getFixVariant(Character c) {
+        return PTAssistantLayerManager.PTLM.getLayer().getFixVariant(c);
+    }
+
+    @SuppressWarnings("unused")
+    private void performDummyTest(Relation r) {
+        List<Relation> primitives = new ArrayList<>(1);
+        primitives.add(r);
+        Builder builder = TestError.builder(this, Severity.WARNING, ERROR_CODE_DIRECTION);
+        builder.message(tr("PT: dummy test warning"));
+        builder.primitives(primitives);
+        errors.add(builder.build());
+    }
 
 }
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/RouteChecker.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/RouteChecker.java	(revision 33416)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/RouteChecker.java	(revision 33417)
@@ -94,7 +94,7 @@
      */
     private int countGaps(List<RelationMember> waysToCheck) {
-    	int numberOfGaps = 0;
+        int numberOfGaps = 0;
 
-    	WayConnectionTypeCalculator connectionTypeCalculator = new WayConnectionTypeCalculator();
+        WayConnectionTypeCalculator connectionTypeCalculator = new WayConnectionTypeCalculator();
         final List<WayConnectionType> links = connectionTypeCalculator.updateLinks(waysToCheck);
         for (int i = 0; i < links.size(); i++) {
@@ -102,6 +102,6 @@
             if(!(i == 0 || link.linkPrev) || !(i == links.size() - 1 || link.linkNext)
                     || link.direction == null || WayConnectionType.Direction.NONE.equals(link.direction)) {
-            	numberOfGaps++;
-            	i++;
+                numberOfGaps++;
+                i++;
             }
         }
@@ -124,5 +124,5 @@
     protected static Command fixSortingError(TestError testError) {
         if (testError.getCode() != PTAssistantValidatorTest.ERROR_CODE_SORTING
-        		&& testError.getCode() != PTAssistantValidatorTest.ERROR_CODE_PARTIAL_SORTING) {
+                && testError.getCode() != PTAssistantValidatorTest.ERROR_CODE_PARTIAL_SORTING) {
             return null;
         }
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/SegmentChecker.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/SegmentChecker.java	(revision 33416)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/SegmentChecker.java	(revision 33417)
@@ -49,1088 +49,1088 @@
 public class SegmentChecker extends Checker {
 
-	/* PTRouteSegments that have been validated and are correct */
-	private static List<PTRouteSegment> correctSegments = new ArrayList<>();
-
-	/* PTRouteSegments that are wrong, stored in case the user calls the fix */
-	protected static HashMap<TestError, PTRouteSegment> wrongSegments = new HashMap<>();
-	protected static HashMap<Builder, PTRouteSegment> wrongSegmentBuilders = new HashMap<>();
-
-	/* Manager of the PTStops and PTWays of the current route */
-	private PTRouteDataManager manager;
-
-	/* Assigns PTStops to nearest PTWays and stores that correspondence */
-	private StopToWayAssigner assigner;
-
-	public SegmentChecker(Relation relation, Test test) {
-
-		super(relation, test);
-
-		this.manager = new PTRouteDataManager(relation);
-
-		for (RelationMember rm : manager.getFailedMembers()) {
-			List<Relation> primitives = new ArrayList<>(1);
-			primitives.add(relation);
-			List<OsmPrimitive> highlighted = new ArrayList<>(1);
-			highlighted.add(rm.getMember());
-			Builder builder = TestError.builder(this.test, Severity.WARNING,
-					PTAssistantValidatorTest.ERROR_CODE_RELATION_MEMBER_ROLES);
-			builder.message(tr("PT: Relation member roles do not match tags"));
-			builder.primitives(primitives);
-			builder.highlight(highlighted);
-			TestError e = builder.build();
-			this.errors.add(e);
-		}
-
-		this.assigner = new StopToWayAssigner(manager.getPTWays());
-
-	}
-
-	/**
-	 * Returns the number of route segments that have been already successfully
-	 * verified
-	 *
-	 * @return the number of route segments
-	 */
-	public static int getCorrectSegmentCount() {
-		return correctSegments.size();
-	}
-
-	/**
-	 * Adds the given correct segment to the list of correct segments without
-	 * checking its correctness
-	 *
-	 * @param segment
-	 *            to add to the list of correct segments
-	 */
-	public static synchronized void addCorrectSegment(PTRouteSegment segment) {
-		for (PTRouteSegment correctSegment : correctSegments) {
-			if (correctSegment.equalsRouteSegment(segment)) {
-				return;
-			}
-		}
-		correctSegments.add(segment);
-	}
-
-	/**
-	 * Used for unit tests
-	 *
-	 * @param error
-	 *            test error
-	 * @return wrong route segment
-	 */
-	protected static PTRouteSegment getWrongSegment(TestError error) {
-		return wrongSegments.get(error);
-	}
-
-	public void performFirstStopTest() {
-
-		performEndStopTest(manager.getFirstStop());
-
-	}
-
-	public void performLastStopTest() {
-
-		performEndStopTest(manager.getLastStop());
-
-	}
-
-	private void performEndStopTest(PTStop endStop) {
-
-		if (endStop == null) {
-			return;
-		}
-
-		/*
-		 * This test checks: (1) that a stop position exists; (2) that it is the
-		 * first or last node of its parent ways which belong to this route.
-		 */
-
-		if (endStop.getStopPosition() == null) {
-
-			List<Node> potentialStopPositionList = endStop.findPotentialStopPositions();
-			List<Node> stopPositionsOfThisRoute = new ArrayList<>();
-			boolean containsAtLeastOneStopPositionAsFirstOrLastNode = false;
-
-			for (Node potentialStopPosition : potentialStopPositionList) {
-
-				int belongsToWay = belongsToAWayOfThisRoute(potentialStopPosition);
-
-				if (belongsToWay == 0) {
-					stopPositionsOfThisRoute.add(potentialStopPosition);
-					containsAtLeastOneStopPositionAsFirstOrLastNode = true;
-				}
-
-				if (belongsToWay == 1) {
-					stopPositionsOfThisRoute.add(potentialStopPosition);
-				}
-			}
-
-			if (stopPositionsOfThisRoute.isEmpty()) {
-				List<Relation> primitives = new ArrayList<>(1);
-				primitives.add(relation);
-				List<OsmPrimitive> highlighted = new ArrayList<>(1);
-				highlighted.add(endStop.getPlatform());
-				Builder builder = TestError.builder(this.test, Severity.WARNING,
-						PTAssistantValidatorTest.ERROR_CODE_END_STOP);
-				builder.message(tr("PT: Route should start and end with a stop_position"));
-				builder.primitives(primitives);
-				builder.highlight(highlighted);
-				TestError e = builder.build();
-				this.errors.add(e);
-				return;
-			}
-
-			if (stopPositionsOfThisRoute.size() == 1) {
-				endStop.setStopPosition(stopPositionsOfThisRoute.get(0));
-			}
-
-			// At this point, there is at least one stop_position for this
-			// endStop:
-			if (!containsAtLeastOneStopPositionAsFirstOrLastNode) {
-				List<Relation> primitives = new ArrayList<>(1);
-				primitives.add(relation);
-				List<OsmPrimitive> highlighted = new ArrayList<>();
-				highlighted.addAll(stopPositionsOfThisRoute);
-
-				Builder builder = TestError.builder(this.test, Severity.WARNING,
-						PTAssistantValidatorTest.ERROR_CODE_SPLIT_WAY);
-				builder.message(tr("PT: First or last way needs to be split"));
-				builder.primitives(primitives);
-				builder.highlight(highlighted);
-				TestError e = builder.build();
-				this.errors.add(e);
-			}
-
-		} else {
-
-			// if the stop_position is known:
-			int belongsToWay = this.belongsToAWayOfThisRoute(endStop.getStopPosition());
-
-			if (belongsToWay == 1) {
-
-				List<Relation> primitives = new ArrayList<>(1);
-				primitives.add(relation);
-				List<OsmPrimitive> highlighted = new ArrayList<>();
-				highlighted.add(endStop.getStopPosition());
-				Builder builder = TestError.builder(this.test, Severity.WARNING,
-						PTAssistantValidatorTest.ERROR_CODE_SPLIT_WAY);
-				builder.message(tr("PT: First or last way needs to be split"));
-				builder.primitives(primitives);
-				builder.highlight(highlighted);
-				TestError e = builder.build();
-				this.errors.add(e);
-			}
-		}
-
-	}
-
-	/**
-	 * Checks if the given node belongs to the ways of this route.
-	 *
-	 * @param node
-	 *            Node to be checked
-	 * @return 1 if belongs only as an inner node, 0 if belongs as a first or
-	 *         last node for at least one way, -1 if does not belong to any way.
-	 */
-	private int belongsToAWayOfThisRoute(Node node) {
-
-		boolean contains = false;
-
-		List<PTWay> ptways = manager.getPTWays();
-		for (PTWay ptway : ptways) {
-			List<Way> ways = ptway.getWays();
-			for (Way way : ways) {
-				if (way.containsNode(node)) {
-
-					if (way.firstNode().equals(node) || way.lastNode().equals(node)) {
-						return 0;
-					}
-
-					contains = true;
-				}
-			}
-		}
-
-		if (contains) {
-			return 1;
-		}
-
-		return -1;
-	}
-
-	public void performStopNotServedTest() {
-		for (PTStop stop : manager.getPTStops()) {
-			Way way = assigner.get(stop);
-			if (way == null) {
-				createStopError(stop);
-			}
-		}
-	}
-
-	/**
-	 * Performs the stop-by-stop test by visiting each segment between two
-	 * consecutive stops and checking if the ways between them are correct
-	 */
-	public void performStopByStopTest() {
-
-		if (manager.getPTStopCount() < 2) {
-			return;
-		}
-
-		List<OsmPrimitive> lastCreatedBuilderHighlighted = null;
-
-		// Check each route segment:
-		for (int i = 1; i < manager.getPTStopCount(); i++) {
-
-			PTStop startStop = manager.getPTStops().get(i - 1);
-			PTStop endStop = manager.getPTStops().get(i);
-
-			Way startWay = assigner.get(startStop);
-			Way endWay = assigner.get(endStop);
-			if (startWay == null || endWay == null || (startWay == endWay && startWay == manager.getLastWay())) {
-				continue;
-			}
-
-			List<PTWay> segmentWays = manager.getPTWaysBetween(startWay, endWay);
-
-			Node firstNode = findFirstNodeOfRouteSegmentInDirectionOfTravel(segmentWays.get(0));
-
-			if (firstNode == null) {
-				// check if this error has just been reported:
-				if (wrongSegmentBuilders.isEmpty() && lastCreatedBuilderHighlighted != null && lastCreatedBuilderHighlighted.size() == 1
-						&& lastCreatedBuilderHighlighted.get(0) == startWay) {
-					// do nothing, this error has already been reported in
-					// the previous route segment
-				} else {
-					List<Relation> primitives = new ArrayList<>(1);
-					primitives.add(relation);
-					List<OsmPrimitive> highlighted = new ArrayList<>();
-					highlighted.add(startWay);
-					Builder builder = TestError.builder(this.test, Severity.WARNING,
-							PTAssistantValidatorTest.ERROR_CODE_STOP_BY_STOP);
-					builder.primitives(primitives);
-					builder.highlight(highlighted);
-					PTRouteSegment routeSegment = new PTRouteSegment(startStop, endStop, segmentWays, relation);
-					wrongSegmentBuilders.put(builder, routeSegment);
-				}
-				continue;
-			}
-
-			PTWay wronglySortedPtway = existingWaySortingIsWrong(segmentWays.get(0), firstNode,
-					segmentWays.get(segmentWays.size() - 1));
-			if (wronglySortedPtway == null) { // i.e. if the sorting is correct:
-				PTRouteSegment routeSegment = new PTRouteSegment(startStop, endStop, segmentWays, relation);
-				addCorrectSegment(routeSegment);
-			} else { // i.e. if the sorting is wrong:
-				PTRouteSegment routeSegment = new PTRouteSegment(startStop, endStop, segmentWays, relation);
-				// TestError error = this.errors.get(this.errors.size() - 1);
-				// wrongSegments.put(error, routeSegment);
-
-				List<Relation> primitives = new ArrayList<>(1);
-				primitives.add(relation);
-				List<OsmPrimitive> highlighted = new ArrayList<>();
-				highlighted.add(startStop.getStopPosition());
-				highlighted.add(endStop.getStopPosition());
-				Builder builder = TestError.builder(this.test, Severity.WARNING,
-						PTAssistantValidatorTest.ERROR_CODE_STOP_BY_STOP);
-				builder.primitives(primitives);
-				builder.highlight(highlighted);
-				lastCreatedBuilderHighlighted = highlighted;
-				wrongSegmentBuilders.put(builder, routeSegment);
-			}
-		}
-	}
-
-	/**
-	 * Creates a TestError and adds it to the list of errors for a stop that is
-	 * not served.
-	 *
-	 * @param stop
-	 *            stop
-	 */
-	private void createStopError(PTStop stop) {
-		List<Relation> primitives = new ArrayList<>(1);
-		primitives.add(relation);
-		List<OsmPrimitive> highlighted = new ArrayList<>();
-		OsmPrimitive stopPrimitive = stop.getPlatform();
-		if (stopPrimitive == null) {
-			stopPrimitive = stop.getStopPosition();
-		}
-		highlighted.add(stopPrimitive);
-		Builder builder = TestError.builder(this.test, Severity.WARNING,
-				PTAssistantValidatorTest.ERROR_CODE_STOP_NOT_SERVED);
-		builder.message(tr("PT: Stop not served"));
-		builder.primitives(primitives);
-		builder.highlight(highlighted);
-		TestError e = builder.build();
-		this.errors.add(e);
-	}
-
-	private Node findFirstNodeOfRouteSegmentInDirectionOfTravel(PTWay startWay) {
-
-		// 1) at first check if one of the first or last node of the first ptway
-		// is a deadend node:
-		Node[] startWayEndnodes = startWay.getEndNodes();
-		if (isDeadendNode(startWayEndnodes[0])) {
-			return startWayEndnodes[0];
-		}
-		if (isDeadendNode(startWayEndnodes[1])) {
-			return startWayEndnodes[1];
-		}
-
-		// 2) failing that, check which node this startWay shares with the
-		// following way:
-		PTWay nextWay = manager.getNextPTWay(startWay);
-		if (nextWay == null) {
-			return null;
-		}
-		PTWay wayAfterNext = manager.getNextPTWay(nextWay);
-		Node[] nextWayEndnodes = nextWay.getEndNodes();
-		if ((startWayEndnodes[0] == nextWayEndnodes[0] && startWayEndnodes[1] == nextWayEndnodes[1])
-				|| (startWayEndnodes[0] == nextWayEndnodes[1] && startWayEndnodes[1] == nextWayEndnodes[0])) {
-			// if this is a split roundabout:
-			Node[] wayAfterNextEndnodes = wayAfterNext.getEndNodes();
-			if (startWayEndnodes[0] == wayAfterNextEndnodes[0] || startWayEndnodes[0] == wayAfterNextEndnodes[1]) {
-				return startWayEndnodes[0];
-			}
-			if (startWayEndnodes[1] == wayAfterNextEndnodes[0] || startWayEndnodes[1] == wayAfterNextEndnodes[1]) {
-				return startWayEndnodes[1];
-			}
-		}
-
-		if (startWayEndnodes[0] == nextWayEndnodes[0] || startWayEndnodes[0] == nextWayEndnodes[1]) {
-			return startWayEndnodes[1];
-		}
-		if (startWayEndnodes[1] == nextWayEndnodes[0] || startWayEndnodes[1] == nextWayEndnodes[1]) {
-			return startWayEndnodes[0];
-		}
-
-		return null;
-
-	}
-
-	private boolean isDeadendNode(Node node) {
-		int count = 0;
-		for (PTWay ptway : manager.getPTWays()) {
-			List<Way> ways = ptway.getWays();
-			for (Way way : ways) {
-				if (way.firstNode() == node || way.lastNode() == node) {
-					count++;
-				}
-			}
-		}
-		return count == 1;
-	}
-
-	/**
-	 * Finds the deadend node closest to the given node represented by its
-	 * coordinates
-	 *
-	 * @param coord
-	 *            coordinates of the givenn node
-	 * @param deadendNodes
-	 *            dead end nodes
-	 * @return the closest deadend node
-	 */
-	@SuppressWarnings("unused")
-	private Node findClosestDeadendNode(LatLon coord, List<Node> deadendNodes) {
-
-		Node closestDeadendNode = null;
-		double minSqDistance = Double.MAX_VALUE;
-		for (Node deadendNode : deadendNodes) {
-			double distanceSq = coord.distanceSq(deadendNode.getCoor());
-			if (distanceSq < minSqDistance) {
-				minSqDistance = distanceSq;
-				closestDeadendNode = deadendNode;
-			}
-		}
-		return closestDeadendNode;
-
-	}
-
-	/**
-	 * Checks if the existing sorting of the given route segment is correct
-	 *
-	 * @param start
-	 *            PTWay assigned to the first stop of the segment
-	 * @param startWayPreviousNodeInDirectionOfTravel
-	 *            Node if the start way which is furthest away from the rest of
-	 *            the route
-	 * @param end
-	 *            PTWay assigned to the end stop of the segment
-	 * @return null if the sorting is correct, or the wrongly sorted PTWay
-	 *         otherwise.
-	 */
-	private PTWay existingWaySortingIsWrong(PTWay start, Node startWayPreviousNodeInDirectionOfTravel, PTWay end) {
-
-		if (start == end) {
-			// if both PTStops are on the same PTWay
-			// return true;
-			return null;
-		}
-
-		PTWay current = start;
-		Node currentNode = startWayPreviousNodeInDirectionOfTravel;
-
-		while (!current.equals(end)) {
-			// "equals" is used here instead of "==" because when the same way
-			// is passed multiple times by the bus, the algorithm should stop no
-			// matter which of the geometrically equal PTWays it finds
-
-			PTWay nextPTWayAccortingToExistingSorting = manager.getNextPTWay(current);
-
-			// if current contains an unsplit roundabout:
-			if (current.containsUnsplitRoundabout()) {
-				currentNode = manager.getCommonNode(current, nextPTWayAccortingToExistingSorting);
-				if (currentNode == null) {
-
-					return current;
-
-				}
-			} else {
-				// if this is a regular way, not an unsplit roundabout
-
-				// find the next node in direction of travel (which is part of
-				// the PTWay start):
-				currentNode = getOppositeEndNode(current, currentNode);
-
-				List<PTWay> nextWaysInDirectionOfTravel = this.findNextPTWaysInDirectionOfTravel(current, currentNode);
-
-				if (!nextWaysInDirectionOfTravel.contains(nextPTWayAccortingToExistingSorting)) {
-					return current;
-
-				}
-			}
-
-			current = nextPTWayAccortingToExistingSorting;
-
-		}
-
-		return null;
-	}
-
-	/**
-	 * Will return the same node if the way is an unsplit roundabout
-	 *
-	 * @param way
-	 *            way
-	 * @param node
-	 *            node
-	 * @return the same node if the way is an unsplit roundabout
-	 */
-	private Node getOppositeEndNode(Way way, Node node) {
-
-		if (node == way.firstNode()) {
-			return way.lastNode();
-		}
-
-		if (node == way.lastNode()) {
-			return way.firstNode();
-		}
-
-		return null;
-	}
-
-	/**
-	 * Does not work correctly for unsplit roundabouts
-	 *
-	 * @param ptway
-	 *            way
-	 * @param node
-	 *            node
-	 * @return node
-	 */
-	private Node getOppositeEndNode(PTWay ptway, Node node) {
-		if (ptway.isWay()) {
-			return getOppositeEndNode(ptway.getWays().get(0), node);
-		}
-
-		Way firstWay = ptway.getWays().get(0);
-		Way lastWay = ptway.getWays().get(ptway.getWays().size() - 1);
-		Node oppositeNode = node;
-		if (firstWay.firstNode() == node || firstWay.lastNode() == node) {
-			for (int i = 0; i < ptway.getWays().size(); i++) {
-				oppositeNode = getOppositeEndNode(ptway.getWays().get(i), oppositeNode);
-			}
-			return oppositeNode;
-		} else if (lastWay.firstNode() == node || lastWay.lastNode() == node) {
-			for (int i = ptway.getWays().size() - 1; i >= 0; i--) {
-				oppositeNode = getOppositeEndNode(ptway.getWays().get(i), oppositeNode);
-			}
-			return oppositeNode;
-		}
-
-		return null;
-
-	}
-
-	/**
-	 * Finds the next ways for the route stop-by-stop parsing procedure
-	 *
-	 * @param currentWay
-	 *            current way
-	 * @param nextNodeInDirectionOfTravel
-	 *            next node in direction of travel
-	 * @return the next ways for the route stop-by-stop parsing procedure
-	 */
-	private List<PTWay> findNextPTWaysInDirectionOfTravel(PTWay currentWay, Node nextNodeInDirectionOfTravel) {
-
-		List<PTWay> nextPtways = new ArrayList<>();
-
-		List<PTWay> ptways = manager.getPTWays();
-
-		for (PTWay ptway : ptways) {
-
-			if (ptway != currentWay) {
-				for (Way way : ptway.getWays()) {
-					if (way.containsNode(nextNodeInDirectionOfTravel)) {
-						nextPtways.add(ptway);
-					}
-				}
-			}
-		}
-
-		return nextPtways;
-
-	}
-
-	protected static boolean isFixable(TestError testError) {
-
-		/*-
-		 * When is an error fixable (outdated)?
-		 * - if there is a correct segment
-		 * - if it can be fixed by sorting
-		 * - if the route is compete even without some ways
-		 * - if simple routing closes the gap
-		 */
-
-		if (testError.getCode() == PTAssistantValidatorTest.ERROR_CODE_STOP_BY_STOP) {
-			return true;
-		}
-
-		return false;
-
-	}
-
-	@SuppressWarnings("unused")
-	private static boolean isFixableByUsingCorrectSegment(TestError testError) {
-		PTRouteSegment wrongSegment = wrongSegments.get(testError);
-		PTRouteSegment correctSegment = null;
-		for (PTRouteSegment segment : correctSegments) {
-			if (wrongSegment.getFirstStop().equalsStop(segment.getFirstStop())
-					&& wrongSegment.getLastStop().equalsStop(segment.getLastStop())) {
-				correctSegment = segment;
-				break;
-			}
-		}
-		return correctSegment != null;
-	}
-
-	@SuppressWarnings("unused")
-	private static boolean isFixableBySortingAndRemoval(TestError testError) {
-		PTRouteSegment wrongSegment = wrongSegments.get(testError);
-		List<List<PTWay>> fixVariants = wrongSegment.getFixVariants();
-		if (!fixVariants.isEmpty()) {
-			return true;
-		}
-		return false;
-	}
-
-	/**
-	 * Finds fixes using sorting and removal.
-	 */
-	protected void findFixes() {
-
-		for (Builder builder : wrongSegmentBuilders.keySet()) {
-
-			if (wrongSegmentBuilders.get(builder).getRelation() == this.relation) {
-
-				findFix(builder);
-
-			}
-		}
-
-	}
-
-	/**
-	 * Modifies the error messages of the stop-by-stop test errors depending on how many fixes each of them has.
-	 */
-	protected static void modifyStopByStopErrorMessages() {
-
-		for (Entry<Builder, PTRouteSegment> entry : SegmentChecker.wrongSegmentBuilders.entrySet()) {
-
-			// change the error code based on the availability of fixes:
-			Builder builder = entry.getKey();
-			PTRouteSegment wrongSegment = entry.getValue();
-			List<PTRouteSegment> correctSegmentsForThisError = new ArrayList<>();
-			for (PTRouteSegment segment : correctSegments) {
-				if (wrongSegment.getFirstWay().getUniqueId() == segment.getFirstWay().getUniqueId()
-						&& wrongSegment.getLastWay().getUniqueId() == segment.getLastWay().getUniqueId()) {
-					correctSegmentsForThisError.add(segment);
-				}
-			}
-
-			int numberOfFixes = correctSegmentsForThisError.size();
-
-			if (numberOfFixes == 0) {
-				numberOfFixes = wrongSegment.getFixVariants().size();
-			}
-			if (numberOfFixes == 0) {
-				for (PTRouteSegment segment : correctSegments) {
-					if (wrongSegment.getFirstStop().equalsStop(segment.getFirstStop())
-							&& wrongSegment.getLastStop().equalsStop(segment.getLastStop())) {
-						correctSegmentsForThisError.add(segment);
-					}
-				}
-				numberOfFixes = correctSegmentsForThisError.size();
-			}
-
-			// change the error message:
-			if (numberOfFixes == 0) {
-				builder.message(tr("PT: Problem in the route segment with no automatic fix"));
-			} else if (numberOfFixes == 1) {
-				builder.message(tr("PT: Problem in the route segment with one automatic fix"));
-			} else {
-				builder.message("PT: Problem in the route segment with several automatic fixes");
-			}
-
-		}
-
-	}
-
-	/**
-	 * This method assumes that the first and the second ways of the route
-	 * segment are correctly connected. If they are not, the error will be
-	 * marked as not fixable.
-	 *
-	 * @param testError
-	 *            test error
-	 */
-	private void findFix(Builder builder) {
-
-		PTRouteSegment wrongSegment = wrongSegmentBuilders.get(builder);
-		PTWay startPTWay = wrongSegment.getFirstPTWay();
-		PTWay endPTWay = wrongSegment.getLastPTWay();
-
-		Node previousNode = findFirstNodeOfRouteSegmentInDirectionOfTravel(startPTWay);
-		if (previousNode == null) {
-			return;
-		}
-
-		List<List<PTWay>> initialFixes = new ArrayList<>();
-		List<PTWay> initialFix = new ArrayList<>();
-		initialFix.add(startPTWay);
-		initialFixes.add(initialFix);
-
-		List<List<PTWay>> allFixes = findWaysForFix(initialFixes, initialFix, previousNode, endPTWay);
-		for (List<PTWay> fix : allFixes) {
-			if (!fix.isEmpty() && fix.get(fix.size() - 1).equals(endPTWay)) {
-				wrongSegment.addFixVariant(fix);
-			}
-		}
-
-	}
-
-	/**
-	 * Recursive method to parse the route segment
-	 *
-	 * @param allFixes
-	 *            all fixes
-	 * @param currentFix
-	 *            current fix
-	 * @param previousNode
-	 *            previous node
-	 * @param endWay
-	 *            end way
-	 * @return list of list of ways
-	 */
-	private List<List<PTWay>> findWaysForFix(List<List<PTWay>> allFixes, List<PTWay> currentFix, Node previousNode,
-			PTWay endWay) {
-
-		PTWay currentWay = currentFix.get(currentFix.size() - 1);
-		Node nextNode = getOppositeEndNode(currentWay, previousNode);
-
-		List<PTWay> nextWays = this.findNextPTWaysInDirectionOfTravel(currentWay, nextNode);
-
-		if (nextWays.size() > 1) {
-			for (int i = 1; i < nextWays.size(); i++) {
-				List<PTWay> newFix = new ArrayList<>();
-				newFix.addAll(currentFix);
-				newFix.add(nextWays.get(i));
-				allFixes.add(newFix);
-				if (!nextWays.get(i).equals(endWay) && !currentFix.contains(nextWays.get(i))) {
-					allFixes = findWaysForFix(allFixes, newFix, nextNode, endWay);
-				}
-			}
-		}
-
-		if (!nextWays.isEmpty()) {
-			boolean contains = currentFix.contains(nextWays.get(0));
-			currentFix.add(nextWays.get(0));
-			if (!nextWays.get(0).equals(endWay) && !contains) {
-				allFixes = findWaysForFix(allFixes, currentFix, nextNode, endWay);
-			}
-		}
-
-		return allFixes;
-	}
-
-	/**
-	 * Fixes the error by first searching in the list of correct segments and
-	 * then trying to sort and remove existing route relation members
-	 *
-	 * @param testError
-	 *            test error
-	 * @return fix command
-	 */
-	protected static Command fixError(TestError testError) {
-
-		// if fix options for another route are displayed in the pt_assistant
-		// layer, clear them:
-		((PTAssistantValidatorTest) testError.getTester()).clearFixVariants();
-
-		PTRouteSegment wrongSegment = wrongSegments.get(testError);
-
-		// 1) try to fix by using the correct segment:
-		List<PTRouteSegment> correctSegmentsForThisError = new ArrayList<>();
-		for (PTRouteSegment segment : correctSegments) {
-			if (wrongSegment.getFirstWay().getUniqueId() == segment.getFirstWay().getUniqueId()
-					&& wrongSegment.getLastWay().getUniqueId() == segment.getLastWay().getUniqueId()) {
-				correctSegmentsForThisError.add(segment);
-			}
-		}
-
-		// if no correct segment found, apply less strict criteria to look for
-		// one:
-		if (correctSegmentsForThisError.isEmpty() && wrongSegment.getFixVariants().isEmpty()) {
-			for (PTRouteSegment segment : correctSegments) {
-				if (wrongSegment.getFirstStop().equalsStop(segment.getFirstStop())
-						&& wrongSegment.getLastStop().equalsStop(segment.getLastStop())) {
-					correctSegmentsForThisError.add(segment);
-				}
-			}
-			if (!correctSegmentsForThisError.isEmpty()) {
-				// display the notification:
-				if (SwingUtilities.isEventDispatchThread()) {
-					Notification notification = new Notification(
-							tr("Warning: the diplayed fix variants are based on less strict criteria"));
-					notification.show();
-				} else {
-					SwingUtilities.invokeLater(new Runnable() {
-						@Override
-						public void run() {
-							Notification notification = new Notification(
-									tr("Warning: the diplayed fix variants are based on less strict criteria"));
-							notification.show();
-						}
-					});
-				}
-			}
-		}
-
-		if (!correctSegmentsForThisError.isEmpty()) {
-
-			if (correctSegmentsForThisError.size() > 1) {
-				List<List<PTWay>> fixVariants = new ArrayList<>();
-				for (PTRouteSegment segment : correctSegmentsForThisError) {
-					fixVariants.add(segment.getPTWays());
-				}
-				displayFixVariants(fixVariants, testError);
-				return null;
-			}
-
-			PTAssistantPlugin.setLastFix(correctSegmentsForThisError.get(0));
-			return carryOutSingleFix(testError, correctSegmentsForThisError.get(0).getPTWays());
-
-		} else if (!wrongSegment.getFixVariants().isEmpty()) {
-			// 2) try to fix using the sorting and removal of existing ways
-			// of the wrong segment:
-			if (wrongSegment.getFixVariants().size() > 1) {
-				displayFixVariants(wrongSegment.getFixVariants(), testError);
-				return null;
-			}
-
-			PTAssistantPlugin.setLastFix(new PTRouteSegment(wrongSegment.getFirstStop(), wrongSegment.getLastStop(),
-					wrongSegment.getFixVariants().get(0), (Relation) testError.getPrimitives().iterator().next()));
-			return carryOutSingleFix(testError, wrongSegment.getFixVariants().get(0));
-		}
-
-		// if there is no fix:
-		return fixErrorByZooming(testError);
-
-	}
-
-	/**
-	 * This is largely a copy of the displayFixVariants() method, adapted for
-	 * use with the key listener
-	 *
-	 * @param fixVariants
-	 *            fix variants
-	 * @param testError
-	 *            test error
-	 */
-	private static void displayFixVariants(List<List<PTWay>> fixVariants, TestError testError) {
-		// find the letters of the fix variants:
-		char alphabet = 'A';
-		final List<Character> allowedCharacters = new ArrayList<>();
-		for (int i = 0; i < fixVariants.size(); i++) {
-			allowedCharacters.add(alphabet);
-			alphabet++;
-		}
-
-		// zoom to problem:
-		final Collection<OsmPrimitive> waysToZoom = new ArrayList<>();
-
-		for (List<PTWay> variants : fixVariants)
-			for(PTWay variant : variants)
-				waysToZoom.add(variant.getWay());
-
-		if (SwingUtilities.isEventDispatchThread()) {
-			AutoScaleAction.zoomTo(waysToZoom);
-		} else {
-			SwingUtilities.invokeLater(new Runnable() {
-				@Override
-				public void run() {
-					AutoScaleAction.zoomTo(waysToZoom);
-				}
-			});
-		}
-
-		// display the fix variants:
-		final PTAssistantValidatorTest test = (PTAssistantValidatorTest) testError.getTester();
-		test.addFixVariants(fixVariants);
-		PTAssistantLayerManager.PTLM.getLayer().repaint((Relation) testError.getPrimitives().iterator().next());
-
-		// prepare the variables for the key listener:
-		final TestError testErrorParameter = testError;
-
-		// // add the key listener:
-		Main.map.mapView.requestFocus();
-		Main.map.mapView.addKeyListener(new KeyListener() {
-
-			@Override
-			public void keyTyped(KeyEvent e) {
-				// TODO Auto-generated method stub
-			}
-
-			@Override
-			public void keyPressed(KeyEvent e) {
-				Character typedKey = e.getKeyChar();
-				Character typedKeyUpperCase = typedKey.toString().toUpperCase().toCharArray()[0];
-				if (allowedCharacters.contains(typedKeyUpperCase)) {
-					Main.map.mapView.removeKeyListener(this);
-					List<PTWay> selectedFix = test.getFixVariant(typedKeyUpperCase);
-					test.clearFixVariants();
-					carryOutSelectedFix(testErrorParameter, selectedFix);
-				}
-				if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
-					Main.map.mapView.removeKeyListener(this);
-					test.clearFixVariants();
-				}
-			}
-
-			@Override
-			public void keyReleased(KeyEvent e) {
-				// TODO Auto-generated method stub
-			}
-		});
-
-		// display the notification:
-		if (SwingUtilities.isEventDispatchThread()) {
-			Notification notification = new Notification(
-					tr("Type letter to select the fix variant or press Escape for no fix"));
-			notification.show();
-		} else {
-			SwingUtilities.invokeLater(new Runnable() {
-				@Override
-				public void run() {
-					Notification notification = new Notification(
-							tr("Type letter to select the fix variant or press Escape for no fix"));
-					notification.show();
-				}
-			});
-		}
-	}
-
-	/**
-	 * Carries out the fix (i.e. modifies the route) after the user has picked
-	 * the fix from several fix variants.
-	 *
-	 * @param testError
-	 *            test error to be fixed
-	 * @param fix
-	 *            the fix variant to be adopted
-	 */
-	private static void carryOutSelectedFix(TestError testError, List<PTWay> fix) {
-		// modify the route:
-		Relation originalRelation = (Relation) testError.getPrimitives().iterator().next();
-		Relation modifiedRelation = new Relation(originalRelation);
-		modifiedRelation.setMembers(getModifiedRelationMembers(testError, fix));
-		ChangeCommand changeCommand = new ChangeCommand(originalRelation, modifiedRelation);
-		Main.main.undoRedo.addNoRedraw(changeCommand);
-		Main.main.undoRedo.afterAdd();
-		PTRouteSegment wrongSegment = wrongSegments.get(testError);
-		wrongSegments.remove(testError);
-		wrongSegment.setPTWays(fix);
-		addCorrectSegment(wrongSegment);
-		PTAssistantPlugin.setLastFixNoGui(wrongSegment);
-
-		// get ways for the fix:
-		List<Way> primitives = new ArrayList<>();
-		for (PTWay ptway : fix) {
-			primitives.addAll(ptway.getWays());
-		}
-
-		// get layer:
-		OsmDataLayer layer = null;
-		List<OsmDataLayer> listOfLayers = Main.getLayerManager().getLayersOfType(OsmDataLayer.class);
-		for (OsmDataLayer osmDataLayer : listOfLayers) {
-			if (osmDataLayer.data == originalRelation.getDataSet()) {
-				layer = osmDataLayer;
-				break;
-			}
-		}
-
-		// create editor:
-		GenericRelationEditor editor = (GenericRelationEditor) RelationEditor.getEditor(layer, originalRelation,
-				originalRelation.getMembersFor(primitives));
-
-		// open editor:
-		editor.setVisible(true);
-
-	}
-
-	/**
-	 * Carries out the fix (i.e. modifies the route) when there is only one fix
-	 * variant.
-	 *
-	 * @param testError
-	 *            test error
-	 * @param fix
-	 *            fix
-	 */
-	private static Command carryOutSingleFix(TestError testError, List<PTWay> fix) {
-
-		// wait:
-		synchronized (SegmentChecker.class) {
-			try {
-				SegmentChecker.class.wait(1500);
-			} catch (InterruptedException e) {
-				e.printStackTrace();
-			}
-		}
-
-		// Zoom to the problematic ways:
-		final Collection<OsmPrimitive> waysToZoom = new ArrayList<>();
-		for (Object highlightedPrimitive : testError.getHighlighted()) {
-			waysToZoom.add((OsmPrimitive) highlightedPrimitive);
-		}
-		if (SwingUtilities.isEventDispatchThread()) {
-			AutoScaleAction.zoomTo(waysToZoom);
-		} else {
-			SwingUtilities.invokeLater(new Runnable() {
-				@Override
-				public void run() {
-					AutoScaleAction.zoomTo(waysToZoom);
-				}
-			});
-		}
-
-		// wait:
-		synchronized (SegmentChecker.class) {
-			try {
-				SegmentChecker.class.wait(1500);
-			} catch (InterruptedException e) {
-				e.printStackTrace();
-			}
-		}
-
-		// modify the route:
-		Relation originalRelation = (Relation) testError.getPrimitives().iterator().next();
-		Relation modifiedRelation = new Relation(originalRelation);
-		modifiedRelation.setMembers(getModifiedRelationMembers(testError, fix));
-		wrongSegments.remove(testError);
-		ChangeCommand changeCommand = new ChangeCommand(originalRelation, modifiedRelation);
-		return changeCommand;
-	}
-
-	/**
-	 * Returns a list of the modified relation members. This list can be used by
-	 * the calling method (relation.setMemers()) to modify the modify the route
-	 * relation. The route relation is not modified by this method. The lists of
-	 * wrong and correct segments are not updated.
-	 *
-	 * @param testError
-	 *            test error to be fixed
-	 * @param fix
-	 *            the fix variant to be adopted
-	 * @return List of modified relation members to be applied to the route
-	 *         relation
-	 */
-	private static List<RelationMember> getModifiedRelationMembers(TestError testError, List<PTWay> fix) {
-		PTRouteSegment wrongSegment = wrongSegments.get(testError);
-		Relation originalRelation = (Relation) testError.getPrimitives().iterator().next();
-
-		// copy stops first:
-		List<RelationMember> modifiedRelationMembers = listStopMembers(originalRelation);
-
-		// copy PTWays last:
-		List<RelationMember> waysOfOriginalRelation = listNotStopMembers(originalRelation);
-		for (int i = 0; i < waysOfOriginalRelation.size(); i++) {
-			if (waysOfOriginalRelation.get(i).getWay() == wrongSegment.getPTWays().get(0).getWays().get(0)) {
-				modifiedRelationMembers.addAll(fix);
-				i = i + wrongSegment.getPTWays().size() - 1;
-			} else {
-				modifiedRelationMembers.add(waysOfOriginalRelation.get(i));
-			}
-		}
-
-		return modifiedRelationMembers;
-	}
-
-	public static void carryOutRepeatLastFix(PTRouteSegment segment) {
-
-		List<TestError> wrongSegmentsToRemove = new ArrayList<>();
-
-		// find all wrong ways that have the same segment:
-		for (TestError testError : wrongSegments.keySet()) {
-			PTRouteSegment wrongSegment = wrongSegments.get(testError);
-			if (wrongSegment.getFirstWay() == segment.getFirstWay()
-					&& wrongSegment.getLastWay() == segment.getLastWay()) {
-				// modify the route:
-				Relation originalRelation = wrongSegment.getRelation();
-				Relation modifiedRelation = new Relation(originalRelation);
-				modifiedRelation.setMembers(getModifiedRelationMembers(testError, segment.getPTWays()));
-				ChangeCommand changeCommand = new ChangeCommand(originalRelation, modifiedRelation);
-				Main.main.undoRedo.addNoRedraw(changeCommand);
-				Main.main.undoRedo.afterAdd();
-				wrongSegmentsToRemove.add(testError);
-			}
-		}
-
-		// update the errors displayed in the validator dialog:
-		List<TestError> modifiedValidatorTestErrors = new ArrayList<>();
-		for (TestError validatorTestError : Main.map.validatorDialog.tree.getErrors()) {
-			if (!wrongSegmentsToRemove.contains(validatorTestError)) {
-				modifiedValidatorTestErrors.add(validatorTestError);
-			}
-		}
-		Main.map.validatorDialog.tree.setErrors(modifiedValidatorTestErrors);
-
-		// update wrong segments:
-		for (TestError testError : wrongSegmentsToRemove) {
-			wrongSegments.remove(testError);
-		}
-
-	}
-
-	/**
-	 * Resets the static list variables (used for unit tests and in Test.startTest() method)
-	 */
-	protected static void reset() {
-		correctSegments.clear();
-		wrongSegments.clear();
-		wrongSegmentBuilders.clear();
-	}
+    /* PTRouteSegments that have been validated and are correct */
+    private static List<PTRouteSegment> correctSegments = new ArrayList<>();
+
+    /* PTRouteSegments that are wrong, stored in case the user calls the fix */
+    protected static HashMap<TestError, PTRouteSegment> wrongSegments = new HashMap<>();
+    protected static HashMap<Builder, PTRouteSegment> wrongSegmentBuilders = new HashMap<>();
+
+    /* Manager of the PTStops and PTWays of the current route */
+    private PTRouteDataManager manager;
+
+    /* Assigns PTStops to nearest PTWays and stores that correspondence */
+    private StopToWayAssigner assigner;
+
+    public SegmentChecker(Relation relation, Test test) {
+
+        super(relation, test);
+
+        this.manager = new PTRouteDataManager(relation);
+
+        for (RelationMember rm : manager.getFailedMembers()) {
+            List<Relation> primitives = new ArrayList<>(1);
+            primitives.add(relation);
+            List<OsmPrimitive> highlighted = new ArrayList<>(1);
+            highlighted.add(rm.getMember());
+            Builder builder = TestError.builder(this.test, Severity.WARNING,
+                    PTAssistantValidatorTest.ERROR_CODE_RELATION_MEMBER_ROLES);
+            builder.message(tr("PT: Relation member roles do not match tags"));
+            builder.primitives(primitives);
+            builder.highlight(highlighted);
+            TestError e = builder.build();
+            this.errors.add(e);
+        }
+
+        this.assigner = new StopToWayAssigner(manager.getPTWays());
+
+    }
+
+    /**
+     * Returns the number of route segments that have been already successfully
+     * verified
+     *
+     * @return the number of route segments
+     */
+    public static int getCorrectSegmentCount() {
+        return correctSegments.size();
+    }
+
+    /**
+     * Adds the given correct segment to the list of correct segments without
+     * checking its correctness
+     *
+     * @param segment
+     *            to add to the list of correct segments
+     */
+    public static synchronized void addCorrectSegment(PTRouteSegment segment) {
+        for (PTRouteSegment correctSegment : correctSegments) {
+            if (correctSegment.equalsRouteSegment(segment)) {
+                return;
+            }
+        }
+        correctSegments.add(segment);
+    }
+
+    /**
+     * Used for unit tests
+     *
+     * @param error
+     *            test error
+     * @return wrong route segment
+     */
+    protected static PTRouteSegment getWrongSegment(TestError error) {
+        return wrongSegments.get(error);
+    }
+
+    public void performFirstStopTest() {
+
+        performEndStopTest(manager.getFirstStop());
+
+    }
+
+    public void performLastStopTest() {
+
+        performEndStopTest(manager.getLastStop());
+
+    }
+
+    private void performEndStopTest(PTStop endStop) {
+
+        if (endStop == null) {
+            return;
+        }
+
+        /*
+         * This test checks: (1) that a stop position exists; (2) that it is the
+         * first or last node of its parent ways which belong to this route.
+         */
+
+        if (endStop.getStopPosition() == null) {
+
+            List<Node> potentialStopPositionList = endStop.findPotentialStopPositions();
+            List<Node> stopPositionsOfThisRoute = new ArrayList<>();
+            boolean containsAtLeastOneStopPositionAsFirstOrLastNode = false;
+
+            for (Node potentialStopPosition : potentialStopPositionList) {
+
+                int belongsToWay = belongsToAWayOfThisRoute(potentialStopPosition);
+
+                if (belongsToWay == 0) {
+                    stopPositionsOfThisRoute.add(potentialStopPosition);
+                    containsAtLeastOneStopPositionAsFirstOrLastNode = true;
+                }
+
+                if (belongsToWay == 1) {
+                    stopPositionsOfThisRoute.add(potentialStopPosition);
+                }
+            }
+
+            if (stopPositionsOfThisRoute.isEmpty()) {
+                List<Relation> primitives = new ArrayList<>(1);
+                primitives.add(relation);
+                List<OsmPrimitive> highlighted = new ArrayList<>(1);
+                highlighted.add(endStop.getPlatform());
+                Builder builder = TestError.builder(this.test, Severity.WARNING,
+                        PTAssistantValidatorTest.ERROR_CODE_END_STOP);
+                builder.message(tr("PT: Route should start and end with a stop_position"));
+                builder.primitives(primitives);
+                builder.highlight(highlighted);
+                TestError e = builder.build();
+                this.errors.add(e);
+                return;
+            }
+
+            if (stopPositionsOfThisRoute.size() == 1) {
+                endStop.setStopPosition(stopPositionsOfThisRoute.get(0));
+            }
+
+            // At this point, there is at least one stop_position for this
+            // endStop:
+            if (!containsAtLeastOneStopPositionAsFirstOrLastNode) {
+                List<Relation> primitives = new ArrayList<>(1);
+                primitives.add(relation);
+                List<OsmPrimitive> highlighted = new ArrayList<>();
+                highlighted.addAll(stopPositionsOfThisRoute);
+
+                Builder builder = TestError.builder(this.test, Severity.WARNING,
+                        PTAssistantValidatorTest.ERROR_CODE_SPLIT_WAY);
+                builder.message(tr("PT: First or last way needs to be split"));
+                builder.primitives(primitives);
+                builder.highlight(highlighted);
+                TestError e = builder.build();
+                this.errors.add(e);
+            }
+
+        } else {
+
+            // if the stop_position is known:
+            int belongsToWay = this.belongsToAWayOfThisRoute(endStop.getStopPosition());
+
+            if (belongsToWay == 1) {
+
+                List<Relation> primitives = new ArrayList<>(1);
+                primitives.add(relation);
+                List<OsmPrimitive> highlighted = new ArrayList<>();
+                highlighted.add(endStop.getStopPosition());
+                Builder builder = TestError.builder(this.test, Severity.WARNING,
+                        PTAssistantValidatorTest.ERROR_CODE_SPLIT_WAY);
+                builder.message(tr("PT: First or last way needs to be split"));
+                builder.primitives(primitives);
+                builder.highlight(highlighted);
+                TestError e = builder.build();
+                this.errors.add(e);
+            }
+        }
+
+    }
+
+    /**
+     * Checks if the given node belongs to the ways of this route.
+     *
+     * @param node
+     *            Node to be checked
+     * @return 1 if belongs only as an inner node, 0 if belongs as a first or
+     *         last node for at least one way, -1 if does not belong to any way.
+     */
+    private int belongsToAWayOfThisRoute(Node node) {
+
+        boolean contains = false;
+
+        List<PTWay> ptways = manager.getPTWays();
+        for (PTWay ptway : ptways) {
+            List<Way> ways = ptway.getWays();
+            for (Way way : ways) {
+                if (way.containsNode(node)) {
+
+                    if (way.firstNode().equals(node) || way.lastNode().equals(node)) {
+                        return 0;
+                    }
+
+                    contains = true;
+                }
+            }
+        }
+
+        if (contains) {
+            return 1;
+        }
+
+        return -1;
+    }
+
+    public void performStopNotServedTest() {
+        for (PTStop stop : manager.getPTStops()) {
+            Way way = assigner.get(stop);
+            if (way == null) {
+                createStopError(stop);
+            }
+        }
+    }
+
+    /**
+     * Performs the stop-by-stop test by visiting each segment between two
+     * consecutive stops and checking if the ways between them are correct
+     */
+    public void performStopByStopTest() {
+
+        if (manager.getPTStopCount() < 2) {
+            return;
+        }
+
+        List<OsmPrimitive> lastCreatedBuilderHighlighted = null;
+
+        // Check each route segment:
+        for (int i = 1; i < manager.getPTStopCount(); i++) {
+
+            PTStop startStop = manager.getPTStops().get(i - 1);
+            PTStop endStop = manager.getPTStops().get(i);
+
+            Way startWay = assigner.get(startStop);
+            Way endWay = assigner.get(endStop);
+            if (startWay == null || endWay == null || (startWay == endWay && startWay == manager.getLastWay())) {
+                continue;
+            }
+
+            List<PTWay> segmentWays = manager.getPTWaysBetween(startWay, endWay);
+
+            Node firstNode = findFirstNodeOfRouteSegmentInDirectionOfTravel(segmentWays.get(0));
+
+            if (firstNode == null) {
+                // check if this error has just been reported:
+                if (wrongSegmentBuilders.isEmpty() && lastCreatedBuilderHighlighted != null && lastCreatedBuilderHighlighted.size() == 1
+                        && lastCreatedBuilderHighlighted.get(0) == startWay) {
+                    // do nothing, this error has already been reported in
+                    // the previous route segment
+                } else {
+                    List<Relation> primitives = new ArrayList<>(1);
+                    primitives.add(relation);
+                    List<OsmPrimitive> highlighted = new ArrayList<>();
+                    highlighted.add(startWay);
+                    Builder builder = TestError.builder(this.test, Severity.WARNING,
+                            PTAssistantValidatorTest.ERROR_CODE_STOP_BY_STOP);
+                    builder.primitives(primitives);
+                    builder.highlight(highlighted);
+                    PTRouteSegment routeSegment = new PTRouteSegment(startStop, endStop, segmentWays, relation);
+                    wrongSegmentBuilders.put(builder, routeSegment);
+                }
+                continue;
+            }
+
+            PTWay wronglySortedPtway = existingWaySortingIsWrong(segmentWays.get(0), firstNode,
+                    segmentWays.get(segmentWays.size() - 1));
+            if (wronglySortedPtway == null) { // i.e. if the sorting is correct:
+                PTRouteSegment routeSegment = new PTRouteSegment(startStop, endStop, segmentWays, relation);
+                addCorrectSegment(routeSegment);
+            } else { // i.e. if the sorting is wrong:
+                PTRouteSegment routeSegment = new PTRouteSegment(startStop, endStop, segmentWays, relation);
+                // TestError error = this.errors.get(this.errors.size() - 1);
+                // wrongSegments.put(error, routeSegment);
+
+                List<Relation> primitives = new ArrayList<>(1);
+                primitives.add(relation);
+                List<OsmPrimitive> highlighted = new ArrayList<>();
+                highlighted.add(startStop.getStopPosition());
+                highlighted.add(endStop.getStopPosition());
+                Builder builder = TestError.builder(this.test, Severity.WARNING,
+                        PTAssistantValidatorTest.ERROR_CODE_STOP_BY_STOP);
+                builder.primitives(primitives);
+                builder.highlight(highlighted);
+                lastCreatedBuilderHighlighted = highlighted;
+                wrongSegmentBuilders.put(builder, routeSegment);
+            }
+        }
+    }
+
+    /**
+     * Creates a TestError and adds it to the list of errors for a stop that is
+     * not served.
+     *
+     * @param stop
+     *            stop
+     */
+    private void createStopError(PTStop stop) {
+        List<Relation> primitives = new ArrayList<>(1);
+        primitives.add(relation);
+        List<OsmPrimitive> highlighted = new ArrayList<>();
+        OsmPrimitive stopPrimitive = stop.getPlatform();
+        if (stopPrimitive == null) {
+            stopPrimitive = stop.getStopPosition();
+        }
+        highlighted.add(stopPrimitive);
+        Builder builder = TestError.builder(this.test, Severity.WARNING,
+                PTAssistantValidatorTest.ERROR_CODE_STOP_NOT_SERVED);
+        builder.message(tr("PT: Stop not served"));
+        builder.primitives(primitives);
+        builder.highlight(highlighted);
+        TestError e = builder.build();
+        this.errors.add(e);
+    }
+
+    private Node findFirstNodeOfRouteSegmentInDirectionOfTravel(PTWay startWay) {
+
+        // 1) at first check if one of the first or last node of the first ptway
+        // is a deadend node:
+        Node[] startWayEndnodes = startWay.getEndNodes();
+        if (isDeadendNode(startWayEndnodes[0])) {
+            return startWayEndnodes[0];
+        }
+        if (isDeadendNode(startWayEndnodes[1])) {
+            return startWayEndnodes[1];
+        }
+
+        // 2) failing that, check which node this startWay shares with the
+        // following way:
+        PTWay nextWay = manager.getNextPTWay(startWay);
+        if (nextWay == null) {
+            return null;
+        }
+        PTWay wayAfterNext = manager.getNextPTWay(nextWay);
+        Node[] nextWayEndnodes = nextWay.getEndNodes();
+        if ((startWayEndnodes[0] == nextWayEndnodes[0] && startWayEndnodes[1] == nextWayEndnodes[1])
+                || (startWayEndnodes[0] == nextWayEndnodes[1] && startWayEndnodes[1] == nextWayEndnodes[0])) {
+            // if this is a split roundabout:
+            Node[] wayAfterNextEndnodes = wayAfterNext.getEndNodes();
+            if (startWayEndnodes[0] == wayAfterNextEndnodes[0] || startWayEndnodes[0] == wayAfterNextEndnodes[1]) {
+                return startWayEndnodes[0];
+            }
+            if (startWayEndnodes[1] == wayAfterNextEndnodes[0] || startWayEndnodes[1] == wayAfterNextEndnodes[1]) {
+                return startWayEndnodes[1];
+            }
+        }
+
+        if (startWayEndnodes[0] == nextWayEndnodes[0] || startWayEndnodes[0] == nextWayEndnodes[1]) {
+            return startWayEndnodes[1];
+        }
+        if (startWayEndnodes[1] == nextWayEndnodes[0] || startWayEndnodes[1] == nextWayEndnodes[1]) {
+            return startWayEndnodes[0];
+        }
+
+        return null;
+
+    }
+
+    private boolean isDeadendNode(Node node) {
+        int count = 0;
+        for (PTWay ptway : manager.getPTWays()) {
+            List<Way> ways = ptway.getWays();
+            for (Way way : ways) {
+                if (way.firstNode() == node || way.lastNode() == node) {
+                    count++;
+                }
+            }
+        }
+        return count == 1;
+    }
+
+    /**
+     * Finds the deadend node closest to the given node represented by its
+     * coordinates
+     *
+     * @param coord
+     *            coordinates of the givenn node
+     * @param deadendNodes
+     *            dead end nodes
+     * @return the closest deadend node
+     */
+    @SuppressWarnings("unused")
+    private Node findClosestDeadendNode(LatLon coord, List<Node> deadendNodes) {
+
+        Node closestDeadendNode = null;
+        double minSqDistance = Double.MAX_VALUE;
+        for (Node deadendNode : deadendNodes) {
+            double distanceSq = coord.distanceSq(deadendNode.getCoor());
+            if (distanceSq < minSqDistance) {
+                minSqDistance = distanceSq;
+                closestDeadendNode = deadendNode;
+            }
+        }
+        return closestDeadendNode;
+
+    }
+
+    /**
+     * Checks if the existing sorting of the given route segment is correct
+     *
+     * @param start
+     *            PTWay assigned to the first stop of the segment
+     * @param startWayPreviousNodeInDirectionOfTravel
+     *            Node if the start way which is furthest away from the rest of
+     *            the route
+     * @param end
+     *            PTWay assigned to the end stop of the segment
+     * @return null if the sorting is correct, or the wrongly sorted PTWay
+     *         otherwise.
+     */
+    private PTWay existingWaySortingIsWrong(PTWay start, Node startWayPreviousNodeInDirectionOfTravel, PTWay end) {
+
+        if (start == end) {
+            // if both PTStops are on the same PTWay
+            // return true;
+            return null;
+        }
+
+        PTWay current = start;
+        Node currentNode = startWayPreviousNodeInDirectionOfTravel;
+
+        while (!current.equals(end)) {
+            // "equals" is used here instead of "==" because when the same way
+            // is passed multiple times by the bus, the algorithm should stop no
+            // matter which of the geometrically equal PTWays it finds
+
+            PTWay nextPTWayAccortingToExistingSorting = manager.getNextPTWay(current);
+
+            // if current contains an unsplit roundabout:
+            if (current.containsUnsplitRoundabout()) {
+                currentNode = manager.getCommonNode(current, nextPTWayAccortingToExistingSorting);
+                if (currentNode == null) {
+
+                    return current;
+
+                }
+            } else {
+                // if this is a regular way, not an unsplit roundabout
+
+                // find the next node in direction of travel (which is part of
+                // the PTWay start):
+                currentNode = getOppositeEndNode(current, currentNode);
+
+                List<PTWay> nextWaysInDirectionOfTravel = this.findNextPTWaysInDirectionOfTravel(current, currentNode);
+
+                if (!nextWaysInDirectionOfTravel.contains(nextPTWayAccortingToExistingSorting)) {
+                    return current;
+
+                }
+            }
+
+            current = nextPTWayAccortingToExistingSorting;
+
+        }
+
+        return null;
+    }
+
+    /**
+     * Will return the same node if the way is an unsplit roundabout
+     *
+     * @param way
+     *            way
+     * @param node
+     *            node
+     * @return the same node if the way is an unsplit roundabout
+     */
+    private Node getOppositeEndNode(Way way, Node node) {
+
+        if (node == way.firstNode()) {
+            return way.lastNode();
+        }
+
+        if (node == way.lastNode()) {
+            return way.firstNode();
+        }
+
+        return null;
+    }
+
+    /**
+     * Does not work correctly for unsplit roundabouts
+     *
+     * @param ptway
+     *            way
+     * @param node
+     *            node
+     * @return node
+     */
+    private Node getOppositeEndNode(PTWay ptway, Node node) {
+        if (ptway.isWay()) {
+            return getOppositeEndNode(ptway.getWays().get(0), node);
+        }
+
+        Way firstWay = ptway.getWays().get(0);
+        Way lastWay = ptway.getWays().get(ptway.getWays().size() - 1);
+        Node oppositeNode = node;
+        if (firstWay.firstNode() == node || firstWay.lastNode() == node) {
+            for (int i = 0; i < ptway.getWays().size(); i++) {
+                oppositeNode = getOppositeEndNode(ptway.getWays().get(i), oppositeNode);
+            }
+            return oppositeNode;
+        } else if (lastWay.firstNode() == node || lastWay.lastNode() == node) {
+            for (int i = ptway.getWays().size() - 1; i >= 0; i--) {
+                oppositeNode = getOppositeEndNode(ptway.getWays().get(i), oppositeNode);
+            }
+            return oppositeNode;
+        }
+
+        return null;
+
+    }
+
+    /**
+     * Finds the next ways for the route stop-by-stop parsing procedure
+     *
+     * @param currentWay
+     *            current way
+     * @param nextNodeInDirectionOfTravel
+     *            next node in direction of travel
+     * @return the next ways for the route stop-by-stop parsing procedure
+     */
+    private List<PTWay> findNextPTWaysInDirectionOfTravel(PTWay currentWay, Node nextNodeInDirectionOfTravel) {
+
+        List<PTWay> nextPtways = new ArrayList<>();
+
+        List<PTWay> ptways = manager.getPTWays();
+
+        for (PTWay ptway : ptways) {
+
+            if (ptway != currentWay) {
+                for (Way way : ptway.getWays()) {
+                    if (way.containsNode(nextNodeInDirectionOfTravel)) {
+                        nextPtways.add(ptway);
+                    }
+                }
+            }
+        }
+
+        return nextPtways;
+
+    }
+
+    protected static boolean isFixable(TestError testError) {
+
+        /*-
+         * When is an error fixable (outdated)?
+         * - if there is a correct segment
+         * - if it can be fixed by sorting
+         * - if the route is compete even without some ways
+         * - if simple routing closes the gap
+         */
+
+        if (testError.getCode() == PTAssistantValidatorTest.ERROR_CODE_STOP_BY_STOP) {
+            return true;
+        }
+
+        return false;
+
+    }
+
+    @SuppressWarnings("unused")
+    private static boolean isFixableByUsingCorrectSegment(TestError testError) {
+        PTRouteSegment wrongSegment = wrongSegments.get(testError);
+        PTRouteSegment correctSegment = null;
+        for (PTRouteSegment segment : correctSegments) {
+            if (wrongSegment.getFirstStop().equalsStop(segment.getFirstStop())
+                    && wrongSegment.getLastStop().equalsStop(segment.getLastStop())) {
+                correctSegment = segment;
+                break;
+            }
+        }
+        return correctSegment != null;
+    }
+
+    @SuppressWarnings("unused")
+    private static boolean isFixableBySortingAndRemoval(TestError testError) {
+        PTRouteSegment wrongSegment = wrongSegments.get(testError);
+        List<List<PTWay>> fixVariants = wrongSegment.getFixVariants();
+        if (!fixVariants.isEmpty()) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Finds fixes using sorting and removal.
+     */
+    protected void findFixes() {
+
+        for (Builder builder : wrongSegmentBuilders.keySet()) {
+
+            if (wrongSegmentBuilders.get(builder).getRelation() == this.relation) {
+
+                findFix(builder);
+
+            }
+        }
+
+    }
+
+    /**
+     * Modifies the error messages of the stop-by-stop test errors depending on how many fixes each of them has.
+     */
+    protected static void modifyStopByStopErrorMessages() {
+
+        for (Entry<Builder, PTRouteSegment> entry : SegmentChecker.wrongSegmentBuilders.entrySet()) {
+
+            // change the error code based on the availability of fixes:
+            Builder builder = entry.getKey();
+            PTRouteSegment wrongSegment = entry.getValue();
+            List<PTRouteSegment> correctSegmentsForThisError = new ArrayList<>();
+            for (PTRouteSegment segment : correctSegments) {
+                if (wrongSegment.getFirstWay().getUniqueId() == segment.getFirstWay().getUniqueId()
+                        && wrongSegment.getLastWay().getUniqueId() == segment.getLastWay().getUniqueId()) {
+                    correctSegmentsForThisError.add(segment);
+                }
+            }
+
+            int numberOfFixes = correctSegmentsForThisError.size();
+
+            if (numberOfFixes == 0) {
+                numberOfFixes = wrongSegment.getFixVariants().size();
+            }
+            if (numberOfFixes == 0) {
+                for (PTRouteSegment segment : correctSegments) {
+                    if (wrongSegment.getFirstStop().equalsStop(segment.getFirstStop())
+                            && wrongSegment.getLastStop().equalsStop(segment.getLastStop())) {
+                        correctSegmentsForThisError.add(segment);
+                    }
+                }
+                numberOfFixes = correctSegmentsForThisError.size();
+            }
+
+            // change the error message:
+            if (numberOfFixes == 0) {
+                builder.message(tr("PT: Problem in the route segment with no automatic fix"));
+            } else if (numberOfFixes == 1) {
+                builder.message(tr("PT: Problem in the route segment with one automatic fix"));
+            } else {
+                builder.message("PT: Problem in the route segment with several automatic fixes");
+            }
+
+        }
+
+    }
+
+    /**
+     * This method assumes that the first and the second ways of the route
+     * segment are correctly connected. If they are not, the error will be
+     * marked as not fixable.
+     *
+     * @param testError
+     *            test error
+     */
+    private void findFix(Builder builder) {
+
+        PTRouteSegment wrongSegment = wrongSegmentBuilders.get(builder);
+        PTWay startPTWay = wrongSegment.getFirstPTWay();
+        PTWay endPTWay = wrongSegment.getLastPTWay();
+
+        Node previousNode = findFirstNodeOfRouteSegmentInDirectionOfTravel(startPTWay);
+        if (previousNode == null) {
+            return;
+        }
+
+        List<List<PTWay>> initialFixes = new ArrayList<>();
+        List<PTWay> initialFix = new ArrayList<>();
+        initialFix.add(startPTWay);
+        initialFixes.add(initialFix);
+
+        List<List<PTWay>> allFixes = findWaysForFix(initialFixes, initialFix, previousNode, endPTWay);
+        for (List<PTWay> fix : allFixes) {
+            if (!fix.isEmpty() && fix.get(fix.size() - 1).equals(endPTWay)) {
+                wrongSegment.addFixVariant(fix);
+            }
+        }
+
+    }
+
+    /**
+     * Recursive method to parse the route segment
+     *
+     * @param allFixes
+     *            all fixes
+     * @param currentFix
+     *            current fix
+     * @param previousNode
+     *            previous node
+     * @param endWay
+     *            end way
+     * @return list of list of ways
+     */
+    private List<List<PTWay>> findWaysForFix(List<List<PTWay>> allFixes, List<PTWay> currentFix, Node previousNode,
+            PTWay endWay) {
+
+        PTWay currentWay = currentFix.get(currentFix.size() - 1);
+        Node nextNode = getOppositeEndNode(currentWay, previousNode);
+
+        List<PTWay> nextWays = this.findNextPTWaysInDirectionOfTravel(currentWay, nextNode);
+
+        if (nextWays.size() > 1) {
+            for (int i = 1; i < nextWays.size(); i++) {
+                List<PTWay> newFix = new ArrayList<>();
+                newFix.addAll(currentFix);
+                newFix.add(nextWays.get(i));
+                allFixes.add(newFix);
+                if (!nextWays.get(i).equals(endWay) && !currentFix.contains(nextWays.get(i))) {
+                    allFixes = findWaysForFix(allFixes, newFix, nextNode, endWay);
+                }
+            }
+        }
+
+        if (!nextWays.isEmpty()) {
+            boolean contains = currentFix.contains(nextWays.get(0));
+            currentFix.add(nextWays.get(0));
+            if (!nextWays.get(0).equals(endWay) && !contains) {
+                allFixes = findWaysForFix(allFixes, currentFix, nextNode, endWay);
+            }
+        }
+
+        return allFixes;
+    }
+
+    /**
+     * Fixes the error by first searching in the list of correct segments and
+     * then trying to sort and remove existing route relation members
+     *
+     * @param testError
+     *            test error
+     * @return fix command
+     */
+    protected static Command fixError(TestError testError) {
+
+        // if fix options for another route are displayed in the pt_assistant
+        // layer, clear them:
+        ((PTAssistantValidatorTest) testError.getTester()).clearFixVariants();
+
+        PTRouteSegment wrongSegment = wrongSegments.get(testError);
+
+        // 1) try to fix by using the correct segment:
+        List<PTRouteSegment> correctSegmentsForThisError = new ArrayList<>();
+        for (PTRouteSegment segment : correctSegments) {
+            if (wrongSegment.getFirstWay().getUniqueId() == segment.getFirstWay().getUniqueId()
+                    && wrongSegment.getLastWay().getUniqueId() == segment.getLastWay().getUniqueId()) {
+                correctSegmentsForThisError.add(segment);
+            }
+        }
+
+        // if no correct segment found, apply less strict criteria to look for
+        // one:
+        if (correctSegmentsForThisError.isEmpty() && wrongSegment.getFixVariants().isEmpty()) {
+            for (PTRouteSegment segment : correctSegments) {
+                if (wrongSegment.getFirstStop().equalsStop(segment.getFirstStop())
+                        && wrongSegment.getLastStop().equalsStop(segment.getLastStop())) {
+                    correctSegmentsForThisError.add(segment);
+                }
+            }
+            if (!correctSegmentsForThisError.isEmpty()) {
+                // display the notification:
+                if (SwingUtilities.isEventDispatchThread()) {
+                    Notification notification = new Notification(
+                            tr("Warning: the diplayed fix variants are based on less strict criteria"));
+                    notification.show();
+                } else {
+                    SwingUtilities.invokeLater(new Runnable() {
+                        @Override
+                        public void run() {
+                            Notification notification = new Notification(
+                                    tr("Warning: the diplayed fix variants are based on less strict criteria"));
+                            notification.show();
+                        }
+                    });
+                }
+            }
+        }
+
+        if (!correctSegmentsForThisError.isEmpty()) {
+
+            if (correctSegmentsForThisError.size() > 1) {
+                List<List<PTWay>> fixVariants = new ArrayList<>();
+                for (PTRouteSegment segment : correctSegmentsForThisError) {
+                    fixVariants.add(segment.getPTWays());
+                }
+                displayFixVariants(fixVariants, testError);
+                return null;
+            }
+
+            PTAssistantPlugin.setLastFix(correctSegmentsForThisError.get(0));
+            return carryOutSingleFix(testError, correctSegmentsForThisError.get(0).getPTWays());
+
+        } else if (!wrongSegment.getFixVariants().isEmpty()) {
+            // 2) try to fix using the sorting and removal of existing ways
+            // of the wrong segment:
+            if (wrongSegment.getFixVariants().size() > 1) {
+                displayFixVariants(wrongSegment.getFixVariants(), testError);
+                return null;
+            }
+
+            PTAssistantPlugin.setLastFix(new PTRouteSegment(wrongSegment.getFirstStop(), wrongSegment.getLastStop(),
+                    wrongSegment.getFixVariants().get(0), (Relation) testError.getPrimitives().iterator().next()));
+            return carryOutSingleFix(testError, wrongSegment.getFixVariants().get(0));
+        }
+
+        // if there is no fix:
+        return fixErrorByZooming(testError);
+
+    }
+
+    /**
+     * This is largely a copy of the displayFixVariants() method, adapted for
+     * use with the key listener
+     *
+     * @param fixVariants
+     *            fix variants
+     * @param testError
+     *            test error
+     */
+    private static void displayFixVariants(List<List<PTWay>> fixVariants, TestError testError) {
+        // find the letters of the fix variants:
+        char alphabet = 'A';
+        final List<Character> allowedCharacters = new ArrayList<>();
+        for (int i = 0; i < fixVariants.size(); i++) {
+            allowedCharacters.add(alphabet);
+            alphabet++;
+        }
+
+        // zoom to problem:
+        final Collection<OsmPrimitive> waysToZoom = new ArrayList<>();
+
+        for (List<PTWay> variants : fixVariants)
+            for(PTWay variant : variants)
+                waysToZoom.add(variant.getWay());
+
+        if (SwingUtilities.isEventDispatchThread()) {
+            AutoScaleAction.zoomTo(waysToZoom);
+        } else {
+            SwingUtilities.invokeLater(new Runnable() {
+                @Override
+                public void run() {
+                    AutoScaleAction.zoomTo(waysToZoom);
+                }
+            });
+        }
+
+        // display the fix variants:
+        final PTAssistantValidatorTest test = (PTAssistantValidatorTest) testError.getTester();
+        test.addFixVariants(fixVariants);
+        PTAssistantLayerManager.PTLM.getLayer().repaint((Relation) testError.getPrimitives().iterator().next());
+
+        // prepare the variables for the key listener:
+        final TestError testErrorParameter = testError;
+
+        // // add the key listener:
+        Main.map.mapView.requestFocus();
+        Main.map.mapView.addKeyListener(new KeyListener() {
+
+            @Override
+            public void keyTyped(KeyEvent e) {
+                // TODO Auto-generated method stub
+            }
+
+            @Override
+            public void keyPressed(KeyEvent e) {
+                Character typedKey = e.getKeyChar();
+                Character typedKeyUpperCase = typedKey.toString().toUpperCase().toCharArray()[0];
+                if (allowedCharacters.contains(typedKeyUpperCase)) {
+                    Main.map.mapView.removeKeyListener(this);
+                    List<PTWay> selectedFix = test.getFixVariant(typedKeyUpperCase);
+                    test.clearFixVariants();
+                    carryOutSelectedFix(testErrorParameter, selectedFix);
+                }
+                if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
+                    Main.map.mapView.removeKeyListener(this);
+                    test.clearFixVariants();
+                }
+            }
+
+            @Override
+            public void keyReleased(KeyEvent e) {
+                // TODO Auto-generated method stub
+            }
+        });
+
+        // display the notification:
+        if (SwingUtilities.isEventDispatchThread()) {
+            Notification notification = new Notification(
+                    tr("Type letter to select the fix variant or press Escape for no fix"));
+            notification.show();
+        } else {
+            SwingUtilities.invokeLater(new Runnable() {
+                @Override
+                public void run() {
+                    Notification notification = new Notification(
+                            tr("Type letter to select the fix variant or press Escape for no fix"));
+                    notification.show();
+                }
+            });
+        }
+    }
+
+    /**
+     * Carries out the fix (i.e. modifies the route) after the user has picked
+     * the fix from several fix variants.
+     *
+     * @param testError
+     *            test error to be fixed
+     * @param fix
+     *            the fix variant to be adopted
+     */
+    private static void carryOutSelectedFix(TestError testError, List<PTWay> fix) {
+        // modify the route:
+        Relation originalRelation = (Relation) testError.getPrimitives().iterator().next();
+        Relation modifiedRelation = new Relation(originalRelation);
+        modifiedRelation.setMembers(getModifiedRelationMembers(testError, fix));
+        ChangeCommand changeCommand = new ChangeCommand(originalRelation, modifiedRelation);
+        Main.main.undoRedo.addNoRedraw(changeCommand);
+        Main.main.undoRedo.afterAdd();
+        PTRouteSegment wrongSegment = wrongSegments.get(testError);
+        wrongSegments.remove(testError);
+        wrongSegment.setPTWays(fix);
+        addCorrectSegment(wrongSegment);
+        PTAssistantPlugin.setLastFixNoGui(wrongSegment);
+
+        // get ways for the fix:
+        List<Way> primitives = new ArrayList<>();
+        for (PTWay ptway : fix) {
+            primitives.addAll(ptway.getWays());
+        }
+
+        // get layer:
+        OsmDataLayer layer = null;
+        List<OsmDataLayer> listOfLayers = Main.getLayerManager().getLayersOfType(OsmDataLayer.class);
+        for (OsmDataLayer osmDataLayer : listOfLayers) {
+            if (osmDataLayer.data == originalRelation.getDataSet()) {
+                layer = osmDataLayer;
+                break;
+            }
+        }
+
+        // create editor:
+        GenericRelationEditor editor = (GenericRelationEditor) RelationEditor.getEditor(layer, originalRelation,
+                originalRelation.getMembersFor(primitives));
+
+        // open editor:
+        editor.setVisible(true);
+
+    }
+
+    /**
+     * Carries out the fix (i.e. modifies the route) when there is only one fix
+     * variant.
+     *
+     * @param testError
+     *            test error
+     * @param fix
+     *            fix
+     */
+    private static Command carryOutSingleFix(TestError testError, List<PTWay> fix) {
+
+        // wait:
+        synchronized (SegmentChecker.class) {
+            try {
+                SegmentChecker.class.wait(1500);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+
+        // Zoom to the problematic ways:
+        final Collection<OsmPrimitive> waysToZoom = new ArrayList<>();
+        for (Object highlightedPrimitive : testError.getHighlighted()) {
+            waysToZoom.add((OsmPrimitive) highlightedPrimitive);
+        }
+        if (SwingUtilities.isEventDispatchThread()) {
+            AutoScaleAction.zoomTo(waysToZoom);
+        } else {
+            SwingUtilities.invokeLater(new Runnable() {
+                @Override
+                public void run() {
+                    AutoScaleAction.zoomTo(waysToZoom);
+                }
+            });
+        }
+
+        // wait:
+        synchronized (SegmentChecker.class) {
+            try {
+                SegmentChecker.class.wait(1500);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+
+        // modify the route:
+        Relation originalRelation = (Relation) testError.getPrimitives().iterator().next();
+        Relation modifiedRelation = new Relation(originalRelation);
+        modifiedRelation.setMembers(getModifiedRelationMembers(testError, fix));
+        wrongSegments.remove(testError);
+        ChangeCommand changeCommand = new ChangeCommand(originalRelation, modifiedRelation);
+        return changeCommand;
+    }
+
+    /**
+     * Returns a list of the modified relation members. This list can be used by
+     * the calling method (relation.setMemers()) to modify the modify the route
+     * relation. The route relation is not modified by this method. The lists of
+     * wrong and correct segments are not updated.
+     *
+     * @param testError
+     *            test error to be fixed
+     * @param fix
+     *            the fix variant to be adopted
+     * @return List of modified relation members to be applied to the route
+     *         relation
+     */
+    private static List<RelationMember> getModifiedRelationMembers(TestError testError, List<PTWay> fix) {
+        PTRouteSegment wrongSegment = wrongSegments.get(testError);
+        Relation originalRelation = (Relation) testError.getPrimitives().iterator().next();
+
+        // copy stops first:
+        List<RelationMember> modifiedRelationMembers = listStopMembers(originalRelation);
+
+        // copy PTWays last:
+        List<RelationMember> waysOfOriginalRelation = listNotStopMembers(originalRelation);
+        for (int i = 0; i < waysOfOriginalRelation.size(); i++) {
+            if (waysOfOriginalRelation.get(i).getWay() == wrongSegment.getPTWays().get(0).getWays().get(0)) {
+                modifiedRelationMembers.addAll(fix);
+                i = i + wrongSegment.getPTWays().size() - 1;
+            } else {
+                modifiedRelationMembers.add(waysOfOriginalRelation.get(i));
+            }
+        }
+
+        return modifiedRelationMembers;
+    }
+
+    public static void carryOutRepeatLastFix(PTRouteSegment segment) {
+
+        List<TestError> wrongSegmentsToRemove = new ArrayList<>();
+
+        // find all wrong ways that have the same segment:
+        for (TestError testError : wrongSegments.keySet()) {
+            PTRouteSegment wrongSegment = wrongSegments.get(testError);
+            if (wrongSegment.getFirstWay() == segment.getFirstWay()
+                    && wrongSegment.getLastWay() == segment.getLastWay()) {
+                // modify the route:
+                Relation originalRelation = wrongSegment.getRelation();
+                Relation modifiedRelation = new Relation(originalRelation);
+                modifiedRelation.setMembers(getModifiedRelationMembers(testError, segment.getPTWays()));
+                ChangeCommand changeCommand = new ChangeCommand(originalRelation, modifiedRelation);
+                Main.main.undoRedo.addNoRedraw(changeCommand);
+                Main.main.undoRedo.afterAdd();
+                wrongSegmentsToRemove.add(testError);
+            }
+        }
+
+        // update the errors displayed in the validator dialog:
+        List<TestError> modifiedValidatorTestErrors = new ArrayList<>();
+        for (TestError validatorTestError : Main.map.validatorDialog.tree.getErrors()) {
+            if (!wrongSegmentsToRemove.contains(validatorTestError)) {
+                modifiedValidatorTestErrors.add(validatorTestError);
+            }
+        }
+        Main.map.validatorDialog.tree.setErrors(modifiedValidatorTestErrors);
+
+        // update wrong segments:
+        for (TestError testError : wrongSegmentsToRemove) {
+            wrongSegments.remove(testError);
+        }
+
+    }
+
+    /**
+     * Resets the static list variables (used for unit tests and in Test.startTest() method)
+     */
+    protected static void reset() {
+        correctSegments.clear();
+        wrongSegments.clear();
+        wrongSegmentBuilders.clear();
+    }
 
 }
Index: /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/actions/SplitRoundaboutTest.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/actions/SplitRoundaboutTest.java	(revision 33416)
+++ /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/actions/SplitRoundaboutTest.java	(revision 33417)
@@ -71,6 +71,6 @@
     @Test
     public void test1() {
-    	Collection<Way> sw1 = splitWay(r1);
-    	assertEquals(4, sw1.size());
+        Collection<Way> sw1 = splitWay(r1);
+        assertEquals(4, sw1.size());
         sw1.forEach(w -> {
             if (w.firstNode().getUniqueId() == 267843779L && w.lastNode().getUniqueId() == 2968718407L)
@@ -89,6 +89,6 @@
     @Test
     public void test2() {
-    	Collection<Way> sw2 = splitWay(r2);
-    	assertEquals(4, sw2.size());
+        Collection<Way> sw2 = splitWay(r2);
+        assertEquals(4, sw2.size());
         sw2.forEach(w -> {
             if(w.firstNode().getUniqueId() == 2158181809L && w.lastNode().getUniqueId() == 2158181798L)
@@ -107,6 +107,6 @@
     @Test
     public void test3() {
-    	Collection<Way> sw3 = splitWay(r3);
-    	assertEquals(4, sw3.size());
+        Collection<Way> sw3 = splitWay(r3);
+        assertEquals(4, sw3.size());
         sw3.forEach(w -> {
             if(w.firstNode().getUniqueId() == 280697532L && w.lastNode().getUniqueId() == 280697452L)
@@ -125,16 +125,16 @@
     @Test
     public void test4() {
-    	Collection<Way> sw4 = splitWay(r4);
-    	assertEquals(10, sw4.size());
-    	Node entry11 = (Node) ds.getPrimitives(p -> p.hasTag("name", "nentry1-1")).iterator().next();
-    	Node exit11 = (Node) ds.getPrimitives(p -> p.hasTag("name", "nexit1-1")).iterator().next();
-    	Node entry12 = (Node) ds.getPrimitives(p -> p.hasTag("name", "nentry1-2")).iterator().next();
-    	Node exit12 = (Node) ds.getPrimitives(p -> p.hasTag("name", "nexit1-2")).iterator().next();
-    	Node entry21 = (Node) ds.getPrimitives(p -> p.hasTag("name", "nentry2-1")).iterator().next();
-    	Node exit21 = (Node) ds.getPrimitives(p -> p.hasTag("name", "nexit2-1")).iterator().next();
-    	Node entry22 = (Node) ds.getPrimitives(p -> p.hasTag("name", "nentry2-2")).iterator().next();
-    	Node exit22 = (Node) ds.getPrimitives(p -> p.hasTag("name", "nexit2-2")).iterator().next();
-    	Node entry3 = (Node) ds.getPrimitives(p -> p.hasTag("name", "nentry3")).iterator().next();
-    	Node exit3 = (Node) ds.getPrimitives(p -> p.hasTag("name", "nexit3")).iterator().next();
+        Collection<Way> sw4 = splitWay(r4);
+        assertEquals(10, sw4.size());
+        Node entry11 = (Node) ds.getPrimitives(p -> p.hasTag("name", "nentry1-1")).iterator().next();
+        Node exit11 = (Node) ds.getPrimitives(p -> p.hasTag("name", "nexit1-1")).iterator().next();
+        Node entry12 = (Node) ds.getPrimitives(p -> p.hasTag("name", "nentry1-2")).iterator().next();
+        Node exit12 = (Node) ds.getPrimitives(p -> p.hasTag("name", "nexit1-2")).iterator().next();
+        Node entry21 = (Node) ds.getPrimitives(p -> p.hasTag("name", "nentry2-1")).iterator().next();
+        Node exit21 = (Node) ds.getPrimitives(p -> p.hasTag("name", "nexit2-1")).iterator().next();
+        Node entry22 = (Node) ds.getPrimitives(p -> p.hasTag("name", "nentry2-2")).iterator().next();
+        Node exit22 = (Node) ds.getPrimitives(p -> p.hasTag("name", "nexit2-2")).iterator().next();
+        Node entry3 = (Node) ds.getPrimitives(p -> p.hasTag("name", "nentry3")).iterator().next();
+        Node exit3 = (Node) ds.getPrimitives(p -> p.hasTag("name", "nexit3")).iterator().next();
 
         sw4.forEach(w -> {
