Index: /applications/editors/josm/plugins/pt_assistant/.checkstyle
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/.checkstyle	(revision 33055)
+++ /applications/editors/josm/plugins/pt_assistant/.checkstyle	(revision 33055)
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<fileset-config file-format-version="1.2.0" simple-config="true" sync-formatter="false">
+  <local-check-config name="JOSM" location="/JOSM/tools/checkstyle/josm_checks.xml" type="project" description="">
+    <additional-data name="protect-config-file" value="false"/>
+  </local-check-config>
+  <fileset name="all" enabled="true" check-config-name="JOSM" local="true">
+    <file-match-pattern match-pattern="." include-pattern="true"/>
+  </fileset>
+  <filter name="DerivedFiles" enabled="true"/>
+  <filter name="FilesFromPackage" enabled="true">
+    <filter-data value=".svn"/>
+    <filter-data value="data"/>
+    <filter-data value="images"/>
+    <filter-data value="resources"/>
+    <filter-data value="styles"/>
+    <filter-data value="scripts"/>
+  </filter>
+</fileset-config>
Index: /applications/editors/josm/plugins/pt_assistant/.project
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/.project	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/.project	(revision 33055)
@@ -16,7 +16,13 @@
 			</arguments>
 		</buildCommand>
+		<buildCommand>
+			<name>net.sf.eclipsecs.core.CheckstyleBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
 	</buildSpec>
 	<natures>
 		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
 	</natures>
 </projectDescription>
Index: /applications/editors/josm/plugins/pt_assistant/.settings/org.eclipse.jdt.ui.prefs
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/.settings/org.eclipse.jdt.ui.prefs	(revision 33055)
+++ /applications/editors/josm/plugins/pt_assistant/.settings/org.eclipse.jdt.ui.prefs	(revision 33055)
@@ -0,0 +1,59 @@
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_functional_interfaces=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=false
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.make_local_variable_final=true
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_type_arguments=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=true
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_lambda=true
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
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 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/PTAssistantPlugin.java	(revision 33055)
@@ -1,3 +1,3 @@
-//License: GPL. For details, see LICENSE file.
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant;
 
@@ -22,90 +22,90 @@
  *
  * @author darya / Darya Golovko
- * 
+ *
  */
 public class PTAssistantPlugin extends Plugin {
 
-	/*
-	 * last fix that was can be re-applied to all similar route segments, can be
-	 * null if unavailable
-	 */
-	private static PTRouteSegment lastFix;
+    /*
+     * last fix that was can be re-applied to all similar route segments, can be
+     * null if unavailable
+     */
+    private static PTRouteSegment lastFix;
 
-	/* item of the Tools menu for adding stop_positions */
-	private JMenuItem addStopPositionMenu;
-	
-	/* item of the Tools menu for repeating the last fix */
-	private static JMenuItem repeatLastFixMenu;
+    /* item of the Tools menu for adding stop_positions */
+    private JMenuItem addStopPositionMenu;
 
-	/**
-	 * Main constructor.
-	 *
-	 * @param info
-	 *            Required information of the plugin. Obtained from the jar
-	 *            file.
-	 */
-	public PTAssistantPlugin(PluginInformation info) {
-		super(info);
+    /* item of the Tools menu for repeating the last fix */
+    private static JMenuItem repeatLastFixMenu;
 
-		OsmValidator.addTest(PTAssistantValidatorTest.class);
+    /**
+     * Main constructor.
+     *
+     * @param info
+     *            Required information of the plugin. Obtained from the jar
+     *            file.
+     */
+    public PTAssistantPlugin(PluginInformation info) {
+        super(info);
 
-		AddStopPositionAction addStopPositionAction = new AddStopPositionAction();
-		addStopPositionMenu = MainMenu.add(Main.main.menu.toolsMenu, addStopPositionAction, false);
-		RepeatLastFixAction repeatLastFixAction = new RepeatLastFixAction();
-		repeatLastFixMenu = MainMenu.add(Main.main.menu.toolsMenu, repeatLastFixAction, false);
+        OsmValidator.addTest(PTAssistantValidatorTest.class);
 
-	}
+        AddStopPositionAction addStopPositionAction = new AddStopPositionAction();
+        addStopPositionMenu = MainMenu.add(Main.main.menu.toolsMenu, addStopPositionAction, false);
+        RepeatLastFixAction repeatLastFixAction = new RepeatLastFixAction();
+        repeatLastFixMenu = MainMenu.add(Main.main.menu.toolsMenu, repeatLastFixAction, false);
 
-	/**
-	 * Called when the JOSM map frame is created or destroyed.
-	 */
-	@Override
-	public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
-		if (oldFrame == null && newFrame != null) {
-			addStopPositionMenu.setEnabled(true);
-			repeatLastFixMenu.setEnabled(false);
-		} else if (oldFrame != null && newFrame == null) {
-			addStopPositionMenu.setEnabled(false);
-			repeatLastFixMenu.setEnabled(false);
-		}
-	}
+    }
 
-	/**
-	 * Sets up the pt_assistant tab in JOSM Preferences
-	 */
-	@Override
-	public PreferenceSetting getPreferenceSetting() {
-		return new PTAssistantPreferenceSetting();
-	}
+    /**
+     * Called when the JOSM map frame is created or destroyed.
+     */
+    @Override
+    public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
+        if (oldFrame == null && newFrame != null) {
+            addStopPositionMenu.setEnabled(true);
+            repeatLastFixMenu.setEnabled(false);
+        } else if (oldFrame != null && newFrame == null) {
+            addStopPositionMenu.setEnabled(false);
+            repeatLastFixMenu.setEnabled(false);
+        }
+    }
 
-	public static PTRouteSegment getLastFix() {
-		return lastFix;
-	}
+    /**
+     * Sets up the pt_assistant tab in JOSM Preferences
+     */
+    @Override
+    public PreferenceSetting getPreferenceSetting() {
+        return new PTAssistantPreferenceSetting();
+    }
 
-	/**
-	 * Remembers the last fix and enables/disables the Repeat last fix menu
-	 * 
-	 * @param segment
-	 *            The last fix, call be null to disable the Repeat last fix menu
-	 */
-	public static void setLastFix(PTRouteSegment segment) {
-		lastFix = segment;
+    public static PTRouteSegment getLastFix() {
+        return lastFix;
+    }
 
-		SwingUtilities.invokeLater(new Runnable() {
-			@Override
-			public void run() {
-				repeatLastFixMenu.setEnabled(segment != null);
-			}
-		});
-	}
+    /**
+     * Remembers the last fix and enables/disables the Repeat last fix menu
+     *
+     * @param segment
+     *            The last fix, call be null to disable the Repeat last fix menu
+     */
+    public static void setLastFix(PTRouteSegment segment) {
+        lastFix = segment;
 
-	/**
-	 * Used in unit tests
-	 * 
-	 * @param segment
-	 */
-	public static void setLastFixNoGui(PTRouteSegment segment) {
-		lastFix = segment;
-	}
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                repeatLastFixMenu.setEnabled(segment != null);
+            }
+        });
+    }
+
+    /**
+     * Used in unit tests
+     *
+     * @param segment route segment
+     */
+    public static void setLastFixNoGui(PTRouteSegment segment) {
+        lastFix = segment;
+    }
 
 }
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 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/AddStopPositionAction.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.actions;
 
@@ -21,5 +22,5 @@
 /**
  * Action to add stop position and split the relevant way
- * 
+ *
  * @author darya
  *
@@ -27,68 +28,67 @@
 public class AddStopPositionAction extends JosmAction {
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -5140181388906670207L;
+    /**
+     *
+     */
+    private static final long serialVersionUID = -5140181388906670207L;
 
-	public AddStopPositionAction() {
-		super(tr("Add stop position"), new ImageProvider("presets/transport", "bus.svg"), tr("Add stop position"),
-				Shortcut.registerShortcut("Add stop position", tr("Add stop position"), KeyEvent.VK_T, Shortcut.NONE),
-				false, "addStopPosition", false);
+    public AddStopPositionAction() {
+        super(tr("Add stop position"), new ImageProvider("presets/transport", "bus.svg"), tr("Add stop position"),
+                Shortcut.registerShortcut("Add stop position", tr("Add stop position"), KeyEvent.VK_T, Shortcut.NONE),
+                false, "addStopPosition", false);
 
-	}
+    }
 
-	/**
-	 * Actions that add the new node, set tags and update the map frame.
-	 */
-	@Override
-	public void actionPerformed(ActionEvent e) {
+    /**
+     * Actions that add the new node, set tags and update the map frame.
+     */
+    @Override
+    public void actionPerformed(ActionEvent e) {
 
-		if (!isEnabled() || !Main.isDisplayingMapView()) {
-			return;
-		}
-		
-		final ActionEvent actionEventParameter = e;
+        if (!isEnabled() || !Main.isDisplayingMapView()) {
+            return;
+        }
 
-		Main.map.mapView.addMouseListener(new MouseAdapter() {
+        final ActionEvent actionEventParameter = e;
 
-			LatLon clickPosition;
+        Main.map.mapView.addMouseListener(new MouseAdapter() {
 
+            LatLon clickPosition;
 
-			@Override
-			public void mouseClicked(MouseEvent e) {
-				
-				if (clickPosition == null) {
-					clickPosition = Main.map.mapView.getLatLon(e.getX(), e.getY());
+            @Override
+            public void mouseClicked(MouseEvent e) {
 
-					Layer activeLayer = Main.getLayerManager().getActiveLayer();
+                if (clickPosition == null) {
+                    clickPosition = Main.map.mapView.getLatLon(e.getX(), e.getY());
 
-					if (activeLayer instanceof OsmDataLayer) {
-						OsmDataLayer osmDataLayer = (OsmDataLayer) activeLayer;
-						Node newNode = new Node(clickPosition);
-						newNode.put("bus", "yes");
-						newNode.put("public_transport", "stop_position");
-						osmDataLayer.data.addPrimitive(newNode);
-						osmDataLayer.data.setSelected(newNode);
-						Main.map.mapView.repaint();
-						
-						// make the stop position node part of the way:
-						JoinNodeWayAction joinNodeWayAction = JoinNodeWayAction.createJoinNodeToWayAction();
-						joinNodeWayAction.actionPerformed(actionEventParameter);
-						
-						// split the way:
-						SplitWayAction splitWayAction = new SplitWayAction();
-						splitWayAction.actionPerformed(actionEventParameter);
+                    Layer activeLayer = Main.getLayerManager().getActiveLayer();
 
-					}
+                    if (activeLayer instanceof OsmDataLayer) {
+                        OsmDataLayer osmDataLayer = (OsmDataLayer) activeLayer;
+                        Node newNode = new Node(clickPosition);
+                        newNode.put("bus", "yes");
+                        newNode.put("public_transport", "stop_position");
+                        osmDataLayer.data.addPrimitive(newNode);
+                        osmDataLayer.data.setSelected(newNode);
+                        Main.map.mapView.repaint();
 
-					Main.map.mapView.removeMouseListener(this);
-					Main.map.mapView.removeMouseMotionListener(this);
+                        // make the stop position node part of the way:
+                        JoinNodeWayAction joinNodeWayAction = JoinNodeWayAction.createJoinNodeToWayAction();
+                        joinNodeWayAction.actionPerformed(actionEventParameter);
 
-				}
-			}
-		});
+                        // split the way:
+                        SplitWayAction splitWayAction = new SplitWayAction();
+                        splitWayAction.actionPerformed(actionEventParameter);
 
-	}
+                    }
+
+                    Main.map.mapView.removeMouseListener(this);
+                    Main.map.mapView.removeMouseMotionListener(this);
+
+                }
+            }
+        });
+
+    }
 
 }
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/DownloadReferrersThread.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/DownloadReferrersThread.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/DownloadReferrersThread.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.actions;
 
@@ -11,41 +12,41 @@
 public class DownloadReferrersThread extends Thread {
 
-	private Node node;
+    private Node node;
 
-	public DownloadReferrersThread(Node node) {
-		super();
-		this.node = node;
+    public DownloadReferrersThread(Node node) {
+        super();
+        this.node = node;
 
-	}
+    }
 
-	@Override
-	public void run() {
+    @Override
+    public void run() {
 
-		synchronized (this) {
+        synchronized (this) {
 
-			Collection<Node> allNodes = node.getDataSet().getNodes();
-			List<PrimitiveId> nodesToBeDownloaded = new ArrayList<PrimitiveId>();
-			for (Node currNode : allNodes) {
-				if (currNode.hasTag("public_transport", "stop_position") || currNode.hasTag("highway", "bus_stop")
-						|| currNode.hasTag("public_transport", "platform") || currNode.hasTag("highway", "platform")
-						|| currNode.hasTag("railway", "platform")) {
-					nodesToBeDownloaded.add(currNode);
-				}
-			}
-			
-			DownloadPrimitivesWithReferrersTask task = new DownloadPrimitivesWithReferrersTask(false, nodesToBeDownloaded, false, true,
-					null, null);
-			Thread t = new Thread(task);
-			t.start();
-			try {
-				t.join();
-			} catch (InterruptedException e) {
-				e.printStackTrace();
-			}
+            Collection<Node> allNodes = node.getDataSet().getNodes();
+            List<PrimitiveId> nodesToBeDownloaded = new ArrayList<>();
+            for (Node currNode : allNodes) {
+                if (currNode.hasTag("public_transport", "stop_position") || currNode.hasTag("highway", "bus_stop")
+                        || currNode.hasTag("public_transport", "platform") || currNode.hasTag("highway", "platform")
+                        || currNode.hasTag("railway", "platform")) {
+                    nodesToBeDownloaded.add(currNode);
+                }
+            }
 
-		}
+            DownloadPrimitivesWithReferrersTask task = new DownloadPrimitivesWithReferrersTask(false, nodesToBeDownloaded, false, true,
+                    null, null);
+            Thread t = new Thread(task);
+            t.start();
+            try {
+                t.join();
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+
+        }
 
 
-	}
+    }
 
 }
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/FixTask.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/FixTask.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/FixTask.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.actions;
 
@@ -20,97 +21,97 @@
 /**
  * This class was copied with minor changes from ValidatorDialog.FixTask
- * 
+ *
  * @author darya
  *
  */
-public class FixTask extends PleaseWaitRunnable { 
-	
-	private final Collection<TestError> testErrors;
-	private boolean canceled;
+public class FixTask extends PleaseWaitRunnable {
 
-	public FixTask(Collection<TestError> testErrors) {
-		super(tr("Fixing errors ..."), false /* don't ignore exceptions */);
-		this.testErrors = testErrors == null ? new ArrayList<TestError>() : testErrors;
-	}
+    private final Collection<TestError> testErrors;
+    private boolean canceled;
 
-	@Override
-	protected void cancel() {
-		this.canceled = true;
-	}
+    public FixTask(Collection<TestError> testErrors) {
+        super(tr("Fixing errors ..."), false /* don't ignore exceptions */);
+        this.testErrors = testErrors == null ? new ArrayList<>() : testErrors;
+    }
 
-	@Override
-	protected void finish() {
-		// do nothing
-	}
+    @Override
+    protected void cancel() {
+        this.canceled = true;
+    }
 
-	protected void fixError(TestError error) throws InterruptedException, InvocationTargetException {
-		if (error.isFixable()) {
-			final Command fixCommand = error.getFix();
-			if (fixCommand != null) {
-				SwingUtilities.invokeAndWait(new Runnable() {
-					@Override
-					public void run() {
-						Main.main.undoRedo.addNoRedraw(fixCommand);
-					}
-				});
-			}
-			// It is wanted to ignore an error if it said fixable, even if
-			// fixCommand was null
-			// This is to fix #5764 and #5773:
-			// a delete command, for example, may be null if all concerned
-			// primitives have already been deleted
-			error.setIgnored(true);
-		}
-	}
+    @Override
+    protected void finish() {
+        // do nothing
+    }
 
-	@Override
-	protected void realRun() throws SAXException, IOException, OsmTransferException {
-		ProgressMonitor monitor = getProgressMonitor();
-		try {
-			monitor.setTicksCount(testErrors.size());
-			int i = 0;
-			SwingUtilities.invokeAndWait(new Runnable() {
-				@Override
-				public void run() {
-					Main.getLayerManager().getEditDataSet().beginUpdate();
-				}
-			});
-			try {
-				for (TestError error : testErrors) {
-					i++;
-					monitor.subTask(tr("Fixing ({0}/{1}): ''{2}''", i, testErrors.size(), error.getMessage()));
-					if (this.canceled)
-						return;
-					fixError(error);
-					monitor.worked(1);
-				}
-			} finally {
-				SwingUtilities.invokeAndWait(new Runnable() {
-					@Override
-					public void run() {
-						Main.getLayerManager().getEditDataSet().endUpdate();
-					}
-				});
-			}
-			monitor.subTask(tr("Updating map ..."));
-			SwingUtilities.invokeAndWait(new Runnable() {
-				@Override
-				public void run() {
-					Main.main.undoRedo.afterAdd();
-					Main.map.repaint();
-					// tree.resetErrors();
-					Main.getLayerManager().getEditDataSet().fireSelectionChanged();
-				}
-			});
-		} catch (InterruptedException | InvocationTargetException e) {
-			// FIXME: signature of realRun should have a generic checked
-			// exception we
-			// could throw here
-			throw new RuntimeException(e);
-		} finally {
-			monitor.finishTask();
-		}
-		
-	}
+    protected void fixError(TestError error) throws InterruptedException, InvocationTargetException {
+        if (error.isFixable()) {
+            final Command fixCommand = error.getFix();
+            if (fixCommand != null) {
+                SwingUtilities.invokeAndWait(new Runnable() {
+                    @Override
+                    public void run() {
+                        Main.main.undoRedo.addNoRedraw(fixCommand);
+                    }
+                });
+            }
+            // It is wanted to ignore an error if it said fixable, even if
+            // fixCommand was null
+            // This is to fix #5764 and #5773:
+            // a delete command, for example, may be null if all concerned
+            // primitives have already been deleted
+            error.setIgnored(true);
+        }
+    }
+
+    @Override
+    protected void realRun() throws SAXException, IOException, OsmTransferException {
+        ProgressMonitor monitor = getProgressMonitor();
+        try {
+            monitor.setTicksCount(testErrors.size());
+            int i = 0;
+            SwingUtilities.invokeAndWait(new Runnable() {
+                @Override
+                public void run() {
+                    Main.getLayerManager().getEditDataSet().beginUpdate();
+                }
+            });
+            try {
+                for (TestError error : testErrors) {
+                    i++;
+                    monitor.subTask(tr("Fixing ({0}/{1}): ''{2}''", i, testErrors.size(), error.getMessage()));
+                    if (this.canceled)
+                        return;
+                    fixError(error);
+                    monitor.worked(1);
+                }
+            } finally {
+                SwingUtilities.invokeAndWait(new Runnable() {
+                    @Override
+                    public void run() {
+                        Main.getLayerManager().getEditDataSet().endUpdate();
+                    }
+                });
+            }
+            monitor.subTask(tr("Updating map ..."));
+            SwingUtilities.invokeAndWait(new Runnable() {
+                @Override
+                public void run() {
+                    Main.main.undoRedo.afterAdd();
+                    Main.map.repaint();
+                    // tree.resetErrors();
+                    Main.getLayerManager().getEditDataSet().fireSelectionChanged();
+                }
+            });
+        } catch (InterruptedException | InvocationTargetException e) {
+            // FIXME: signature of realRun should have a generic checked
+            // exception we
+            // could throw here
+            throw new RuntimeException(e);
+        } finally {
+            monitor.finishTask();
+        }
+
+    }
 
 }
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/IncompleteMembersDownloadThread.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/IncompleteMembersDownloadThread.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/IncompleteMembersDownloadThread.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.actions;
 
@@ -21,71 +22,72 @@
 public class IncompleteMembersDownloadThread extends Thread {
 
-	/**
-	 * Default constructor
-	 */
-	public IncompleteMembersDownloadThread() {
-		super();
+    /**
+     * Default constructor
+     */
+    public IncompleteMembersDownloadThread() {
+        super();
 
-	}
+    }
 
-	@Override
-	public void run() {
+    @Override
+    public void run() {
 
-		try {
-			synchronized (this) {
+        try {
+            synchronized (this) {
 
-				ArrayList<PrimitiveId> list = new ArrayList<>();
+                ArrayList<PrimitiveId> list = new ArrayList<>();
 
-				// if there are selected routes, try adding them first:
-				for (Relation currentSelectedRelation : Main.getLayerManager().getEditDataSet()
-						.getSelectedRelations()) {
-					if (RouteUtils.isTwoDirectionRoute(currentSelectedRelation)) {
-						list.add(currentSelectedRelation);
-					}
-				}
+                // if there are selected routes, try adding them first:
+                for (Relation currentSelectedRelation : Main.getLayerManager().getEditDataSet()
+                        .getSelectedRelations()) {
+                    if (RouteUtils.isTwoDirectionRoute(currentSelectedRelation)) {
+                        list.add(currentSelectedRelation);
+                    }
+                }
 
-				if (list.isEmpty()) {
-					// add all route relations that are of public_transport
-					// version 2:
-					Collection<Relation> allRelations = Main.getLayerManager().getEditDataSet().getRelations();
-					for (Relation currentRelation : allRelations) {
-						if (RouteUtils.isTwoDirectionRoute(currentRelation)) {
-							list.add(currentRelation);
-						}
-					}
-				}
+                if (list.isEmpty()) {
+                    // add all route relations that are of public_transport
+                    // version 2:
+                    Collection<Relation> allRelations = Main.getLayerManager().getEditDataSet().getRelations();
+                    for (Relation currentRelation : allRelations) {
+                        if (RouteUtils.isTwoDirectionRoute(currentRelation)) {
+                            list.add(currentRelation);
+                        }
+                    }
+                }
 
-				// add all stop_positions:
-				Collection<Node> allNodes = Main.getLayerManager().getEditDataSet().getNodes();
-				for (Node currentNode : allNodes) {
-					if (currentNode.hasTag("public_transport", "stop_position")) {
-						List<OsmPrimitive> referrers = currentNode.getReferrers();
-						boolean parentWayExists = false;
-						for (OsmPrimitive referrer : referrers) {
-							if (referrer.getType().equals(OsmPrimitiveType.WAY)) {
-								parentWayExists = true;
-								break;
-							}
-						}
-						if (!parentWayExists) {
-							list.add(currentNode);
+                // add all stop_positions:
+                Collection<Node> allNodes = Main.getLayerManager().getEditDataSet().getNodes();
+                for (Node currentNode : allNodes) {
+                    if (currentNode.hasTag("public_transport", "stop_position")) {
+                        List<OsmPrimitive> referrers = currentNode.getReferrers();
+                        boolean parentWayExists = false;
+                        for (OsmPrimitive referrer : referrers) {
+                            if (referrer.getType().equals(OsmPrimitiveType.WAY)) {
+                                parentWayExists = true;
+                                break;
+                            }
+                        }
+                        if (!parentWayExists) {
+                            list.add(currentNode);
 
-						}
+                        }
 
-					}
-				}
+                    }
+                }
 
-				DownloadPrimitivesWithReferrersTask task = new DownloadPrimitivesWithReferrersTask(false, list, false,
-						true, null, null);
-				Thread t = new Thread(task);
-				t.start();
-				t.join();
+                DownloadPrimitivesWithReferrersTask task = new DownloadPrimitivesWithReferrersTask(false, list, false,
+                        true, null, null);
+                Thread t = new Thread(task);
+                t.start();
+                t.join();
 
-			}
+            }
 
-		} catch (InterruptedException e) {
-			// do nothing in case the download was interrupted
-		}
+        } catch (InterruptedException e) {
+            // do nothing in case the download was interrupted
+            Main.trace(e);
+        }
 
-	}
+    }
 }
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/RepeatLastFixAction.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/RepeatLastFixAction.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/actions/RepeatLastFixAction.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.actions;
 
@@ -15,5 +16,5 @@
 /**
  * Carries out the changes after the Repeat last fix button has been pressed
- * 
+ *
  * @author darya
  *
@@ -21,31 +22,31 @@
 public class RepeatLastFixAction extends JosmAction {
 
-	private static final long serialVersionUID = 2681464946469047054L;
+    private static final long serialVersionUID = 2681464946469047054L;
 
-	/**
-	 * Default constructor
-	 */
-	public RepeatLastFixAction() {
-		super(tr("Repeat last fix"), new ImageProvider("presets/transport", "bus.svg"), tr("Repeat last fix"),
-				Shortcut.registerShortcut("Repeat last fix", tr("Repeat last fix"), KeyEvent.VK_E, Shortcut.NONE),
-				false, "repeatLastFix", false);
+    /**
+     * Default constructor
+     */
+    public RepeatLastFixAction() {
+        super(tr("Repeat last fix"), new ImageProvider("presets/transport", "bus.svg"), tr("Repeat last fix"),
+                Shortcut.registerShortcut("Repeat last fix", tr("Repeat last fix"), KeyEvent.VK_E, Shortcut.NONE),
+                false, "repeatLastFix", false);
 
-	}
+    }
 
-	/**
-	 * Applies the fixes, resets the last fix attribute
-	 */
-	@Override
-	public void actionPerformed(ActionEvent e) {
+    /**
+     * Applies the fixes, resets the last fix attribute
+     */
+    @Override
+    public void actionPerformed(ActionEvent e) {
 
-		if (!isEnabled() || !Main.isDisplayingMapView()) {
-			return;
-		}
+        if (!isEnabled() || !Main.isDisplayingMapView()) {
+            return;
+        }
 
-		SegmentChecker.carryOutRepeatLastFix(PTAssistantPlugin.getLastFix());
+        SegmentChecker.carryOutRepeatLastFix(PTAssistantPlugin.getLastFix());
 
-		PTAssistantPlugin.setLastFix(null);
+        PTAssistantPlugin.setLastFix(null);
 
-	}
+    }
 
 }
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/data/PTRouteDataManager.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/data/PTRouteDataManager.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/data/PTRouteDataManager.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.data;
 
@@ -16,5 +17,5 @@
  * Creates a representation of a route relation in the pt_assistant data model,
  * then maintains a list of PTStops and PTWays of a route.
- * 
+ *
  * @author darya
  *
@@ -22,409 +23,412 @@
 public class PTRouteDataManager {
 
-	/* The route relation */
-	Relation relation;
-
-	/* Stores all relation members that are PTStops */
-	private List<PTStop> ptstops = new ArrayList<>();
-
-	/* Stores all relation members that are PTWays */
-	private List<PTWay> ptways = new ArrayList<>();
-
-	/*
-	 * Stores relation members that could not be created because they are not
-	 * expected in the model for public_transport version 2
-	 */
-	private Set<RelationMember> failedMembers = new HashSet<>();
-
-	public PTRouteDataManager(Relation relation) throws IllegalArgumentException {
-
-		// It is assumed that the relation is a route. Build in a check here
-		// (e.g. from class RouteUtils) if you want to invoke this constructor
-		// from outside the pt_assitant SegmentChecker)
-
-		this.relation = relation;
-
-		PTStop prev = null; // stores the last created PTStop
-
-		for (RelationMember member : this.relation.getMembers()) {
-
-			if (RouteUtils.isPTStop(member)) {
-
-				// First, check if the stop already exists (i.e. there are
-				// consecutive elements that belong to the same stop:
-				boolean stopExists = false;
-
-				if (prev != null) {
-					if (prev.getName() == null || prev.getName().equals("") || member.getMember().get("name") == null
-							|| member.getMember().get("name").equals("")) {
-
-						// if there is no name, check by proximity:
-						// Squared distance of 0.000004 corresponds to
-						// around 100 m
-						if (this.calculateDistanceSq(member, prev) < 0.000001) {
-							stopExists = true;
-						}
-
-					} else {
-
-						// if there is a name, check by name comparison:
-						if (prev.getName().equalsIgnoreCase(member.getMember().get("name"))) {
-
-							stopExists = true;
-						}
-					}
-				}
-
-				// check if there are consecutive elements that belong to
-				// the same stop:
-				if (stopExists) {
-					// this PTStop already exists, so just add a new
-					// element:
-					prev.addStopElement(member);
-					// TODO: something may need to be done if adding the
-					// element
-					// did not succeed. The failure is a result of the same
-					// stop
-					// having >1 stop_position, platform or stop_area.
-				} else {
-					// this PTStop does not exist yet, so create it:
-
-					try {
-						PTStop ptstop = new PTStop(member);
-						ptstops.add(ptstop);
-						prev = ptstop;
-					} catch (IllegalArgumentException ex) {
-						if (ex.getMessage().equals(
-								"The RelationMember type does not match its role " + member.getMember().getName())) {
-							if (!failedMembers.contains(member)) {
-								failedMembers.add(member);
-							}
-						} else {
-							throw ex;
-						}
-					}
-
-				}
-
-			} else if (RouteUtils.isPTWay(member)) {
-
-				PTWay ptway = new PTWay(member);
-				ptways.add(ptway);
-
-			} else {
-				if (!failedMembers.contains(member)) {
-					failedMembers.add(member);
-				}
-
-			}
-
-		}
-	}
-
-	/**
-	 * Calculates the squared distance between the centers of bounding boxes of
-	 * two relation members (which are supposed to be platforms or
-	 * stop_positions)
-	 * 
-	 * @param member1
-	 * @param member2
-	 * @return Squared distance between the centers of the bounding boxes of the
-	 *         given relation members
-	 */
-	private double calculateDistanceSq(RelationMember member1, RelationMember member2) {
-		LatLon coord1 = member1.getMember().getBBox().getCenter();
-		LatLon coord2 = member2.getMember().getBBox().getCenter();
-		return coord1.distanceSq(coord2);
-	}
-
-	/**
-	 * Assigns the given way to a PTWay of this route relation. If multiple
-	 * PTWays contain the same inputWay, the first found PTWay is returned.
-	 * 
-	 * @param inputWay
-	 *            Way to be assigned to a PTWAy of this route relation
-	 * @return PTWay that contains the geometry of the inputWay, null if not
-	 *         found
-	 */
-	public PTWay getPTWay(Way inputWay) {
-
-		for (PTWay curr : ptways) {
-
-			if (curr.isWay() && curr.getWays().get(0) == inputWay) {
-				return curr;
-			}
-
-			if (curr.isRelation()) {
-				for (RelationMember rm : curr.getRelation().getMembers()) {
-					Way wayInNestedRelation = rm.getWay();
-					if (wayInNestedRelation == inputWay) {
-						return curr;
-					}
-				}
-			}
-		}
-
-		return null; // if not found
-	}
-
-	public List<PTStop> getPTStops() {
-		return this.ptstops;
-	}
-
-	public List<PTWay> getPTWays() {
-		return this.ptways;
-	}
-
-	public int getPTStopCount() {
-		return ptstops.size();
-	}
-
-	public int getPTWayCount() {
-		return this.ptways.size();
-	}
-
-	public PTStop getFirstStop() {
-		if (this.ptstops.isEmpty()) {
-			return null;
-		}
-		return this.ptstops.get(0);
-	}
-
-	public PTStop getLastStop() {
-		if (this.ptstops.isEmpty()) {
-			return null;
-		}
-		return this.ptstops.get(ptstops.size() - 1);
-	}
-
-	public Set<RelationMember> getFailedMembers() {
-		return this.failedMembers;
-	}
-
-	/**
-	 * Returns the route relation for which this manager was created:
-	 * 
-	 * @return
-	 */
-	public Relation getRelation() {
-		return this.relation;
-	}
-
-	/**
-	 * Returns a PTStop that matches the given id. Returns null if not found
-	 * 
-	 * @param id
-	 * @return
-	 */
-	public PTStop getPTStop(long id) {
-		for (PTStop stop : this.ptstops) {
-			if (stop.getStopPosition() != null && stop.getStopPosition().getId() == id) {
-				return stop;
-			}
-
-			if (stop.getPlatform() != null && stop.getPlatform().getId() == id) {
-				return stop;
-			}
-		}
-
-		return null;
-	}
-
-	/**
-	 * Returns a PTWay that matches the given id. Returns null if not found
-	 * 
-	 * @param id
-	 * @return
-	 */
-	public PTWay getPTWay(long id) {
-		for (PTWay ptway : this.ptways) {
-			for (Way way : ptway.getWays()) {
-				if (way.getId() == id) {
-					return ptway;
-				}
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Returns all PTWays of this route that contain the given way.
-	 * 
-	 * @param way
-	 * @return
-	 */
-	public List<PTWay> findPTWaysThatContain(Way way) {
-
-		List<PTWay> ptwaysThatContain = new ArrayList<>();
-		for (PTWay ptway : ptways) {
-			if (ptway.getWays().contains(way)) {
-				ptwaysThatContain.add(ptway);
-			}
-		}
-		return ptwaysThatContain;
-	}
-
-	/**
-	 * Returns all PTWays of this route that contain the given node as their
-	 * first or last node.
-	 * 
-	 * @return
-	 */
-	public List<PTWay> findPTWaysThatContainAsEndNode(Node node) {
-
-		List<PTWay> ptwaysThatContain = new ArrayList<>();
-		for (PTWay ptway : ptways) {
-			List<Way> ways = ptway.getWays();
-			if (ways.get(0).firstNode() == node || ways.get(0).lastNode() == node
-					|| ways.get(ways.size() - 1).firstNode() == node || ways.get(ways.size() - 1).lastNode() == node) {
-				ptwaysThatContain.add(ptway);
-			}
-		}
-		return ptwaysThatContain;
-
-	}
-
-	/**
-	 * Checks if at most one PTWay of this route refers to the given node
-	 * 
-	 * @param node
-	 * @return
-	 */
-	public boolean isDeadendNode(Node node) {
-
-		List<PTWay> referringPtways = this.findPTWaysThatContainAsEndNode(node);
-		if (referringPtways.size() <= 1) {
-			return true;
-		}
-		return false;
-	}
-
-	/**
-	 * Returns the PTWay which comes directly after the given ptway according to
-	 * the existing route member sorting
-	 * 
-	 * @param ptway
-	 * @return
-	 */
-	public PTWay getNextPTWay(PTWay ptway) {
-
-		for (int i = 0; i < ptways.size() - 1; i++) {
-			if (ptways.get(i) == ptway) {
-				return ptways.get(i + 1);
-			}
-		}
-		return null;
-
-	}
-
-	/**
-	 * Returns the PTWay which comes directly before the given ptway according
-	 * to the existing route member sorting
-	 * 
-	 * @param ptway
-	 * @return
-	 */
-	public PTWay getPreviousPTWay(PTWay ptway) {
-
-		for (int i = 1; i < ptways.size(); i++) {
-			if (ptways.get(i) == ptway) {
-				return ptways.get(i - 1);
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Returns a sequence of PTWays that are between the start way and the end
-	 * way. The resulting list includes the start and end PTWays.
-	 * 
-	 * @param start
-	 * @param end
-	 * @return
-	 */
-	public List<PTWay> getPTWaysBetween(Way start, Way end) {
-
-		List<Integer> potentialStartIndices = new ArrayList<>();
-		List<Integer> potentialEndIndices = new ArrayList<>();
-
-		for (int i = 0; i < ptways.size(); i++) {
-			if (ptways.get(i).getWays().contains(start)) {
-				potentialStartIndices.add(i);
-			}
-			if (ptways.get(i).getWays().contains(end)) {
-				potentialEndIndices.add(i);
-			}
-		}
-
-		List<int[]> pairList = new ArrayList<>();
-		for (Integer potentialStartIndex : potentialStartIndices) {
-			for (Integer potentialEndIndex : potentialEndIndices) {
-				if (potentialStartIndex <= potentialEndIndex) {
-					int[] pair = { potentialStartIndex, potentialEndIndex };
-					pairList.add(pair);
-				}
-			}
-		}
-
-		int minDifference = Integer.MAX_VALUE;
-		int[] mostSuitablePair = { 0, 0 };
-		for (int[] pair : pairList) {
-			int diff = pair[1] - pair[0];
-			if (diff < minDifference) {
-				minDifference = diff;
-				mostSuitablePair = pair;
-			}
-		}
-
-		List<PTWay> result = new ArrayList<>();
-		for (int i = mostSuitablePair[0]; i <= mostSuitablePair[1]; i++) {
-			result.add(ptways.get(i));
-		}
-		return result;
-	}
-
-	/**
-	 * Returns the common Node of two PTWays or null if there is no common Node.
-	 * If there is more than one common Node, only the first found is returned.
-	 * 
-	 * @param way1
-	 * @param way2
-	 * @return
-	 */
-	public Node getCommonNode(PTWay way1, PTWay way2) {
-
-		List<Way> wayList1 = way1.getWays();
-		List<Way> wayList2 = way2.getWays();
-
-		HashSet<Node> nodeSet1 = new HashSet<>();
-		for (Way w : wayList1) {
-			nodeSet1.addAll(w.getNodes());
-		}
-		HashSet<Node> nodeSet2 = new HashSet<>();
-		for (Way w : wayList2) {
-			nodeSet2.addAll(w.getNodes());
-		}
-
-		for (Node n : nodeSet1) {
-			if (nodeSet2.contains(n)) {
-				return n;
-			}
-		}
-
-		return null;
-	}
-
-	/**
-	 * Returns the last way of this route
-	 * 
-	 * @return
-	 */
-	public Way getLastWay() {
-		PTWay lastPTWay = this.ptways.get(ptways.size() - 1);
-		if (lastPTWay == null) {
-			return null;
-		}
-		return lastPTWay.getWays().get(lastPTWay.getWays().size() - 1);
-	}
+    /* The route relation */
+    Relation relation;
+
+    /* Stores all relation members that are PTStops */
+    private List<PTStop> ptstops = new ArrayList<>();
+
+    /* Stores all relation members that are PTWays */
+    private List<PTWay> ptways = new ArrayList<>();
+
+    /*
+     * Stores relation members that could not be created because they are not
+     * expected in the model for public_transport version 2
+     */
+    private Set<RelationMember> failedMembers = new HashSet<>();
+
+    public PTRouteDataManager(Relation relation) throws IllegalArgumentException {
+
+        // It is assumed that the relation is a route. Build in a check here
+        // (e.g. from class RouteUtils) if you want to invoke this constructor
+        // from outside the pt_assitant SegmentChecker)
+
+        this.relation = relation;
+
+        PTStop prev = null; // stores the last created PTStop
+
+        for (RelationMember member : this.relation.getMembers()) {
+
+            if (RouteUtils.isPTStop(member)) {
+
+                // First, check if the stop already exists (i.e. there are
+                // consecutive elements that belong to the same stop:
+                boolean stopExists = false;
+
+                if (prev != null) {
+                    if (prev.getName() == null || prev.getName().equals("") || member.getMember().get("name") == null
+                            || member.getMember().get("name").equals("")) {
+
+                        // if there is no name, check by proximity:
+                        // Squared distance of 0.000004 corresponds to
+                        // around 100 m
+                        if (this.calculateDistanceSq(member, prev) < 0.000001) {
+                            stopExists = true;
+                        }
+
+                    } else {
+
+                        // if there is a name, check by name comparison:
+                        if (prev.getName().equalsIgnoreCase(member.getMember().get("name"))) {
+
+                            stopExists = true;
+                        }
+                    }
+                }
+
+                // check if there are consecutive elements that belong to
+                // the same stop:
+                if (stopExists) {
+                    // this PTStop already exists, so just add a new
+                    // element:
+                    prev.addStopElement(member);
+                    // TODO: something may need to be done if adding the
+                    // element
+                    // did not succeed. The failure is a result of the same
+                    // stop
+                    // having >1 stop_position, platform or stop_area.
+                } else {
+                    // this PTStop does not exist yet, so create it:
+
+                    try {
+                        PTStop ptstop = new PTStop(member);
+                        ptstops.add(ptstop);
+                        prev = ptstop;
+                    } catch (IllegalArgumentException ex) {
+                        if (ex.getMessage().equals(
+                                "The RelationMember type does not match its role " + member.getMember().getName())) {
+                            if (!failedMembers.contains(member)) {
+                                failedMembers.add(member);
+                            }
+                        } else {
+                            throw ex;
+                        }
+                    }
+
+                }
+
+            } else if (RouteUtils.isPTWay(member)) {
+
+                PTWay ptway = new PTWay(member);
+                ptways.add(ptway);
+
+            } else {
+                if (!failedMembers.contains(member)) {
+                    failedMembers.add(member);
+                }
+
+            }
+
+        }
+    }
+
+    /**
+     * Calculates the squared distance between the centers of bounding boxes of
+     * two relation members (which are supposed to be platforms or
+     * stop_positions)
+     *
+     * @param member1 first member
+     * @param member2 second member
+     * @return Squared distance between the centers of the bounding boxes of the
+     *         given relation members
+     */
+    private double calculateDistanceSq(RelationMember member1, RelationMember member2) {
+        LatLon coord1 = member1.getMember().getBBox().getCenter();
+        LatLon coord2 = member2.getMember().getBBox().getCenter();
+        return coord1.distanceSq(coord2);
+    }
+
+    /**
+     * Assigns the given way to a PTWay of this route relation. If multiple
+     * PTWays contain the same inputWay, the first found PTWay is returned.
+     *
+     * @param inputWay
+     *            Way to be assigned to a PTWAy of this route relation
+     * @return PTWay that contains the geometry of the inputWay, null if not
+     *         found
+     */
+    public PTWay getPTWay(Way inputWay) {
+
+        for (PTWay curr : ptways) {
+
+            if (curr.isWay() && curr.getWays().get(0) == inputWay) {
+                return curr;
+            }
+
+            if (curr.isRelation()) {
+                for (RelationMember rm : curr.getRelation().getMembers()) {
+                    Way wayInNestedRelation = rm.getWay();
+                    if (wayInNestedRelation == inputWay) {
+                        return curr;
+                    }
+                }
+            }
+        }
+
+        return null; // if not found
+    }
+
+    public List<PTStop> getPTStops() {
+        return this.ptstops;
+    }
+
+    public List<PTWay> getPTWays() {
+        return this.ptways;
+    }
+
+    public int getPTStopCount() {
+        return ptstops.size();
+    }
+
+    public int getPTWayCount() {
+        return this.ptways.size();
+    }
+
+    public PTStop getFirstStop() {
+        if (this.ptstops.isEmpty()) {
+            return null;
+        }
+        return this.ptstops.get(0);
+    }
+
+    public PTStop getLastStop() {
+        if (this.ptstops.isEmpty()) {
+            return null;
+        }
+        return this.ptstops.get(ptstops.size() - 1);
+    }
+
+    public Set<RelationMember> getFailedMembers() {
+        return this.failedMembers;
+    }
+
+    /**
+     * Returns the route relation for which this manager was created:
+     *
+     * @return the route relation for which this manager was created
+     */
+    public Relation getRelation() {
+        return this.relation;
+    }
+
+    /**
+     * Returns a PTStop that matches the given id. Returns null if not found
+     *
+     * @param id identifier
+     * @return a PTStop that matches the given id. Returns null if not found
+     */
+    public PTStop getPTStop(long id) {
+        for (PTStop stop : this.ptstops) {
+            if (stop.getStopPosition() != null && stop.getStopPosition().getId() == id) {
+                return stop;
+            }
+
+            if (stop.getPlatform() != null && stop.getPlatform().getId() == id) {
+                return stop;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns a PTWay that matches the given id. Returns null if not found
+     *
+     * @param id identifier
+     * @return a PTWay that matches the given id. Returns null if not found
+     */
+    public PTWay getPTWay(long id) {
+        for (PTWay ptway : this.ptways) {
+            for (Way way : ptway.getWays()) {
+                if (way.getId() == id) {
+                    return ptway;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns all PTWays of this route that contain the given way.
+     *
+     * @param way way
+     * @return all PTWays of this route that contain the given way
+     */
+    public List<PTWay> findPTWaysThatContain(Way way) {
+
+        List<PTWay> ptwaysThatContain = new ArrayList<>();
+        for (PTWay ptway : ptways) {
+            if (ptway.getWays().contains(way)) {
+                ptwaysThatContain.add(ptway);
+            }
+        }
+        return ptwaysThatContain;
+    }
+
+    /**
+     * Returns all PTWays of this route that contain the given node as their
+     * first or last node.
+     *
+     * @return all PTWays of this route that contain the given node as their
+     * first or last node
+     */
+    public List<PTWay> findPTWaysThatContainAsEndNode(Node node) {
+
+        List<PTWay> ptwaysThatContain = new ArrayList<>();
+        for (PTWay ptway : ptways) {
+            List<Way> ways = ptway.getWays();
+            if (ways.get(0).firstNode() == node || ways.get(0).lastNode() == node
+                    || ways.get(ways.size() - 1).firstNode() == node || ways.get(ways.size() - 1).lastNode() == node) {
+                ptwaysThatContain.add(ptway);
+            }
+        }
+        return ptwaysThatContain;
+
+    }
+
+    /**
+     * Checks if at most one PTWay of this route refers to the given node
+     *
+     * @param node node
+     * @return {@code true} if at most one PTWay of this route refers to the given node
+     */
+    public boolean isDeadendNode(Node node) {
+
+        List<PTWay> referringPtways = this.findPTWaysThatContainAsEndNode(node);
+        if (referringPtways.size() <= 1) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Returns the PTWay which comes directly after the given ptway according to
+     * the existing route member sorting
+     *
+     * @param ptway way
+     * @return the PTWay which comes directly after the given ptway according to
+     * the existing route member sorting
+     */
+    public PTWay getNextPTWay(PTWay ptway) {
+
+        for (int i = 0; i < ptways.size() - 1; i++) {
+            if (ptways.get(i) == ptway) {
+                return ptways.get(i + 1);
+            }
+        }
+        return null;
+
+    }
+
+    /**
+     * Returns the PTWay which comes directly before the given ptway according
+     * to the existing route member sorting
+     *
+     * @param ptway way
+     * @return the PTWay which comes directly before the given ptway according
+     * to the existing route member sorting
+     */
+    public PTWay getPreviousPTWay(PTWay ptway) {
+
+        for (int i = 1; i < ptways.size(); i++) {
+            if (ptways.get(i) == ptway) {
+                return ptways.get(i - 1);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns a sequence of PTWays that are between the start way and the end
+     * way. The resulting list includes the start and end PTWays.
+     *
+     * @param start start way
+     * @param end end way
+     * @return a sequence of PTWays that are between the start way and the end way
+     */
+    public List<PTWay> getPTWaysBetween(Way start, Way end) {
+
+        List<Integer> potentialStartIndices = new ArrayList<>();
+        List<Integer> potentialEndIndices = new ArrayList<>();
+
+        for (int i = 0; i < ptways.size(); i++) {
+            if (ptways.get(i).getWays().contains(start)) {
+                potentialStartIndices.add(i);
+            }
+            if (ptways.get(i).getWays().contains(end)) {
+                potentialEndIndices.add(i);
+            }
+        }
+
+        List<int[]> pairList = new ArrayList<>();
+        for (Integer potentialStartIndex : potentialStartIndices) {
+            for (Integer potentialEndIndex : potentialEndIndices) {
+                if (potentialStartIndex <= potentialEndIndex) {
+                    int[] pair = {potentialStartIndex, potentialEndIndex};
+                    pairList.add(pair);
+                }
+            }
+        }
+
+        int minDifference = Integer.MAX_VALUE;
+        int[] mostSuitablePair = {0, 0};
+        for (int[] pair : pairList) {
+            int diff = pair[1] - pair[0];
+            if (diff < minDifference) {
+                minDifference = diff;
+                mostSuitablePair = pair;
+            }
+        }
+
+        List<PTWay> result = new ArrayList<>();
+        for (int i = mostSuitablePair[0]; i <= mostSuitablePair[1]; i++) {
+            result.add(ptways.get(i));
+        }
+        return result;
+    }
+
+    /**
+     * Returns the common Node of two PTWays or null if there is no common Node.
+     * If there is more than one common Node, only the first found is returned.
+     *
+     * @param way1 first way
+     * @param way2 second way
+     * @return the common Node of two PTWays or null if there is no common Node
+     */
+    public Node getCommonNode(PTWay way1, PTWay way2) {
+
+        List<Way> wayList1 = way1.getWays();
+        List<Way> wayList2 = way2.getWays();
+
+        HashSet<Node> nodeSet1 = new HashSet<>();
+        for (Way w : wayList1) {
+            nodeSet1.addAll(w.getNodes());
+        }
+        HashSet<Node> nodeSet2 = new HashSet<>();
+        for (Way w : wayList2) {
+            nodeSet2.addAll(w.getNodes());
+        }
+
+        for (Node n : nodeSet1) {
+            if (nodeSet2.contains(n)) {
+                return n;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the last way of this route
+     *
+     * @return the last way of this route
+     */
+    public Way getLastWay() {
+        PTWay lastPTWay = this.ptways.get(ptways.size() - 1);
+        if (lastPTWay == null) {
+            return null;
+        }
+        return lastPTWay.getWays().get(lastPTWay.getWays().size() - 1);
+    }
 
 }
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 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/data/PTRouteSegment.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.data;
 
@@ -12,5 +13,5 @@
  * will be two route segments between each pair of consecutive stops, one in
  * each direction.
- * 
+ *
  * @author darya
  *
@@ -19,192 +20,192 @@
 public class PTRouteSegment {
 
-	/* first stop of the route segment */
-	private PTStop firstStop;
-	
-	/* last stop of the route segment */
-	private PTStop lastStop;
-	
-	/* ptways that belong to this route segment */
-	private List<PTWay> ptways;
-	
-	/* fix variants available for this route segment */
-	private List<List<PTWay>> fixVariants;
-	
-	/* route relation for which this route segment was created */
-	private Relation relation;
-
-	/**
-	 * Constructor
-	 * @param firstStop first stop of the route segment
-	 * @param lastStop last stop of the route segment
-	 * @param ways ways PTWays that belong to this route segment
-	 * @param relation the route relation for which this route segment is created
-	 */
-	public PTRouteSegment(PTStop firstStop, PTStop lastStop, List<PTWay> ways, Relation relation) {
-		this.firstStop = firstStop;
-		this.lastStop = lastStop;
-		this.ptways = new ArrayList<>(ways.size());
-		ptways.addAll(ways);
-		fixVariants = new ArrayList<>();
-		this.relation = relation;
-	}
-
-	/**
-	 * Returns the PTWays of this route segment
-	 * @return
-	 */
-	public List<PTWay> getPTWays() {
-		return this.ptways;
-	}
-
-	/**
-	 * Sets the PTWays of this route segment to the given list
-	 * @param ptwayList
-	 */
-	public void setPTWays(List<PTWay> ptwayList) {
-		this.ptways = ptwayList;
-		this.fixVariants.clear();
-	}
-
-	/**
-	 * Returns the first stop of this route segment
-	 * @return
-	 */
-	public PTStop getFirstStop() {
-		return this.firstStop;
-	}
-	
-	/**
-	 * Returns the last stop of this route segment
-	 * @return
-	 */
-	public PTStop getLastStop() {
-		return this.lastStop;
-	}
-
-	/**
-	 * Returns the first PTWay of this route segment
-	 * @return
-	 */
-	public PTWay getFirstPTWay() {
-		if (ptways.isEmpty()) {
-			return null;
-		}
-		return ptways.get(0);
-	}
-
-	/**
-	 * Returns the last PTWay of this route segment
-	 * @return
-	 */
-	public PTWay getLastPTWay() {
-		if (ptways.isEmpty()) {
-			return null;
-		}
-		return ptways.get(ptways.size() - 1);
-	}
-	
-	/**
-	 * Returns the first way of this route segment
-	 * @return
-	 */
-	public Way getFirstWay() {
-		if (ptways.isEmpty()) {
-			return null;
-		}
-		return ptways.get(0).getWays().get(0);
-	}
-	
-	/**
-	 * Returns the last way of this route segment
-	 * @return
-	 */
-	public Way getLastWay() {
-		if (ptways.isEmpty()) {
-			return null;
-		}
-		List<Way> waysOfLast = ptways.get(ptways.size() - 1).getWays();
-		return waysOfLast.get(waysOfLast.size() - 1);
-	}
-
-	/**
-	 * Adds the new fix variant if an identical fix variant (i.e. same ways) is
-	 * not already contained in the list of the fix variants of this.
-	 * 
-	 * @param list the PTWays of the new fix variant
-	 */
-	public synchronized void addFixVariant(List<PTWay> list) {
-		List<Way> otherWays = new ArrayList<>();
-		for (PTWay ptway : list) {
-			otherWays.addAll(ptway.getWays());
-		}
-
-		for (List<PTWay> fixVariant : this.fixVariants) {
-			List<Way> thisWays = new ArrayList<>();
-			for (PTWay ptway : fixVariant) {
-				thisWays.addAll(ptway.getWays());
-			}
-			boolean listsEqual = (thisWays.size() == otherWays.size());
-			if (listsEqual) {
-				for (int i = 0; i < thisWays.size(); i++) {
-					if (thisWays.get(i).getId() != otherWays.get(i).getId()) {
-						listsEqual = false;
-						break;
-					}
-				}
-			}
-			if (listsEqual) {
-				return;
-			}
-		}
-
-		this.fixVariants.add(list);
-	}
-
-	/**
-	 * Returns the fix variants stored for this route segment
-	 * @return
-	 */
-	public List<List<PTWay>> getFixVariants() {
-		return this.fixVariants;
-	}
-	
-	/**
-	 * Returns the route relation for which this route segment was created
-	 * @return
-	 */
-	public Relation getRelation() {
-		return this.relation;
-	}
-
-	/**
-	 * Checks if this and the other route segments are equal
-	 * 
-	 * @param other
-	 * @return
-	 */
-	public boolean equalsRouteSegment(PTRouteSegment other) {
-
-		List<Way> thisWays = new ArrayList<>();
-		for (PTWay ptway : this.ptways) {
-			thisWays.addAll(ptway.getWays());
-		}
-		List<Way> otherWays = new ArrayList<>();
-		for (PTWay ptway : other.getPTWays()) {
-			otherWays.addAll(ptway.getWays());
-		}
-
-		if (thisWays.size() != otherWays.size()) {
-			return false;
-		}
-
-		for (int i = 0; i < thisWays.size(); i++) {
-			if (thisWays.get(i).getId() != otherWays.get(i).getId()) {
-				return false;
-			}
-		}
-
-		return true;
-	}
+    /* first stop of the route segment */
+    private PTStop firstStop;
+
+    /* last stop of the route segment */
+    private PTStop lastStop;
+
+    /* ptways that belong to this route segment */
+    private List<PTWay> ptways;
+
+    /* fix variants available for this route segment */
+    private List<List<PTWay>> fixVariants;
+
+    /* route relation for which this route segment was created */
+    private Relation relation;
+
+    /**
+     * Constructor
+     * @param firstStop first stop of the route segment
+     * @param lastStop last stop of the route segment
+     * @param ways ways PTWays that belong to this route segment
+     * @param relation the route relation for which this route segment is created
+     */
+    public PTRouteSegment(PTStop firstStop, PTStop lastStop, List<PTWay> ways, Relation relation) {
+        this.firstStop = firstStop;
+        this.lastStop = lastStop;
+        this.ptways = new ArrayList<>(ways.size());
+        ptways.addAll(ways);
+        fixVariants = new ArrayList<>();
+        this.relation = relation;
+    }
+
+    /**
+     * Returns the PTWays of this route segment
+     * @return the PTWays of this route segment
+     */
+    public List<PTWay> getPTWays() {
+        return this.ptways;
+    }
+
+    /**
+     * Sets the PTWays of this route segment to the given list
+     * @param ptwayList list of ways
+     */
+    public void setPTWays(List<PTWay> ptwayList) {
+        this.ptways = ptwayList;
+        this.fixVariants.clear();
+    }
+
+    /**
+     * Returns the first stop of this route segment
+     * @return the first stop of this route segment
+     */
+    public PTStop getFirstStop() {
+        return this.firstStop;
+    }
+
+    /**
+     * Returns the last stop of this route segment
+     * @return the last stop of this route segment
+     */
+    public PTStop getLastStop() {
+        return this.lastStop;
+    }
+
+    /**
+     * Returns the first PTWay of this route segment
+     * @return the first PTWay of this route segment
+     */
+    public PTWay getFirstPTWay() {
+        if (ptways.isEmpty()) {
+            return null;
+        }
+        return ptways.get(0);
+    }
+
+    /**
+     * Returns the last PTWay of this route segment
+     * @return the last PTWay of this route segment
+     */
+    public PTWay getLastPTWay() {
+        if (ptways.isEmpty()) {
+            return null;
+        }
+        return ptways.get(ptways.size() - 1);
+    }
+
+    /**
+     * Returns the first way of this route segment
+     * @return the first way of this route segment
+     */
+    public Way getFirstWay() {
+        if (ptways.isEmpty()) {
+            return null;
+        }
+        return ptways.get(0).getWays().get(0);
+    }
+
+    /**
+     * Returns the last way of this route segment
+     * @return the last way of this route segment
+     */
+    public Way getLastWay() {
+        if (ptways.isEmpty()) {
+            return null;
+        }
+        List<Way> waysOfLast = ptways.get(ptways.size() - 1).getWays();
+        return waysOfLast.get(waysOfLast.size() - 1);
+    }
+
+    /**
+     * Adds the new fix variant if an identical fix variant (i.e. same ways) is
+     * not already contained in the list of the fix variants of this.
+     *
+     * @param list the PTWays of the new fix variant
+     */
+    public synchronized void addFixVariant(List<PTWay> list) {
+        List<Way> otherWays = new ArrayList<>();
+        for (PTWay ptway : list) {
+            otherWays.addAll(ptway.getWays());
+        }
+
+        for (List<PTWay> fixVariant : this.fixVariants) {
+            List<Way> thisWays = new ArrayList<>();
+            for (PTWay ptway : fixVariant) {
+                thisWays.addAll(ptway.getWays());
+            }
+            boolean listsEqual = (thisWays.size() == otherWays.size());
+            if (listsEqual) {
+                for (int i = 0; i < thisWays.size(); i++) {
+                    if (thisWays.get(i).getId() != otherWays.get(i).getId()) {
+                        listsEqual = false;
+                        break;
+                    }
+                }
+            }
+            if (listsEqual) {
+                return;
+            }
+        }
+
+        this.fixVariants.add(list);
+    }
+
+    /**
+     * Returns the fix variants stored for this route segment
+     * @return the fix variants stored for this route segment
+     */
+    public List<List<PTWay>> getFixVariants() {
+        return this.fixVariants;
+    }
+
+    /**
+     * Returns the route relation for which this route segment was created
+     * @return the route relation for which this route segment was created
+     */
+    public Relation getRelation() {
+        return this.relation;
+    }
+
+    /**
+     * Checks if this and the other route segments are equal
+     *
+     * @param other other route segment
+     * @return {@code true} if this and the other route segments are equal
+     */
+    public boolean equalsRouteSegment(PTRouteSegment other) {
+
+        List<Way> thisWays = new ArrayList<>();
+        for (PTWay ptway : this.ptways) {
+            thisWays.addAll(ptway.getWays());
+        }
+        List<Way> otherWays = new ArrayList<>();
+        for (PTWay ptway : other.getPTWays()) {
+            otherWays.addAll(ptway.getWays());
+        }
+
+        if (thisWays.size() != otherWays.size()) {
+            return false;
+        }
+
+        for (int i = 0; i < thisWays.size(); i++) {
+            if (thisWays.get(i).getId() != otherWays.get(i).getId()) {
+                return false;
+            }
+        }
+
+        return true;
+    }
 
 }
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/data/PTStop.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/data/PTStop.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/data/PTStop.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.data;
 
@@ -14,5 +15,5 @@
 /**
  * Model a stop with one or two elements (platform and/or stop_position)
- * 
+ *
  * @author darya
  *
@@ -20,193 +21,193 @@
 public class PTStop extends RelationMember {
 
-	/* stop_position element of this stop */
-	private Node stopPosition = null;
-
-	/* platform element of this stop */
-	private OsmPrimitive platform = null;
-
-	/* the name of this stop */
-	private String name = "";
-
-	/**
-	 * Constructor
-	 * 
-	 * @param other
-	 * @throws IllegalArgumentException
-	 *             if the given relation member does not fit to the data model
-	 *             used in the plugin
-	 */
-	public PTStop(RelationMember other) throws IllegalArgumentException {
-
-		super(other);
-
-		// if ((other.hasRole("stop") || other.hasRole("stop_entry_only") ||
-		// other.hasRole("stop_exit_only"))
-		// && other.getType().equals(OsmPrimitiveType.NODE)) {
-
-		if (other.getMember().hasTag("public_transport", "stop_position")) {
-
-			this.stopPosition = other.getNode();
-			this.name = stopPosition.get("name");
-
-			// } else if (other.getRole().equals("platform") ||
-			// other.getRole().equals("platform_entry_only")
-			// || other.getRole().equals("platform_exit_only")) {
-		} else if (other.getMember().hasTag("highway", "bus_stop")
-				|| other.getMember().hasTag("public_transport", "platform")
-				|| other.getMember().hasTag("highway", "platform") || other.getMember().hasTag("railway", "platform")) {
-
-			this.platform = other.getMember();
-			this.name = platform.get("name");
-
-		} else {
-			throw new IllegalArgumentException(
-					"The RelationMember type does not match its role " + other.getMember().getName());
-		}
-
-	}
-
-	/**
-	 * Adds the given element to the stop after a check
-	 * 
-	 * @param member
-	 *            Element to add
-	 * @return true if added successfully, false otherwise. A false value
-	 *         indicates either that the OsmPrimitiveType of the given
-	 *         RelationMember does not match its role or that this PTStop
-	 *         already has an attribute with that role.
-	 */
-	protected boolean addStopElement(RelationMember member) {
-
-		// each element is only allowed once per stop
-
-		// add stop position:
-		// if (member.hasRole("stop") || member.hasRole("stop_entry_only") ||
-		// member.hasRole("stop_exit_only")) {
-		if (member.getMember().hasTag("public_transport", "stop_position")) {
-			if (member.getType().equals(OsmPrimitiveType.NODE) && stopPosition == null) {
-				this.stopPosition = member.getNode();
-				return true;
-			}
-		}
-
-		// add platform:
-		// if (member.getRole().equals("platform") ||
-		// member.getRole().equals("platform_entry_only")
-		// || member.getRole().equals("platform_exit_only")) {
-		if (member.getMember().hasTag("highway", "bus_stop")
-				|| member.getMember().hasTag("public_transport", "platform")
-				|| member.getMember().hasTag("highway", "platform")
-				|| member.getMember().hasTag("railway", "platform")) {
-			if (platform == null) {
-				platform = member.getMember();
-				return true;
-			}
-		}
-
-		return false;
-
-	}
-
-	/**
-	 * Returns the stop_position for this PTstop. If the stop_position is not
-	 * available directly, the method searches for a stop_area relation
-	 * 
-	 * @return
-	 */
-	public Node getStopPosition() {
-
-		return this.stopPosition;
-	}
-
-	/**
-	 * Returns platform (including platform_entry_only and platform_exit_only)
-	 * 
-	 * @return
-	 */
-	public OsmPrimitive getPlatform() {
-		return this.platform;
-	}
-
-	/**
-	 * Returns the name of this stop
-	 * @return
-	 */
-	protected String getName() {
-		return this.name;
-	}
-
-	/**
-	 * Sets the stop_position for this stop to the given node
-	 * @param newStopPosition
-	 */
-	public void setStopPosition(Node newStopPosition) {
-
-		this.stopPosition = newStopPosition;
-
-	}
-
-	/**
-	 * Finds potential stop_positions of the platform of this PTStop. It only
-	 * makes sense to call this method if the stop_position attribute is null.
-	 * The stop_positions are potential because they may refer to a different
-	 * route, which this method does not check.
-	 * 
-	 * @return List of potential stop_positions for this PTStop
-	 */
-	public List<Node> findPotentialStopPositions() {
-
-		ArrayList<Node> potentialStopPositions = new ArrayList<>();
-
-		if (platform == null) {
-			return potentialStopPositions;
-		}
-
-		// Look for a stop position within 0.002 degrees (around 100 m) of this
-		// platform:
-
-		LatLon platformCenter = platform.getBBox().getCenter();
-		Double ax = platformCenter.getX() - 0.002;
-		Double bx = platformCenter.getX() + 0.002;
-		Double ay = platformCenter.getY() - 0.002;
-		Double by = platformCenter.getY() + 0.002;
-		BBox platformBBox = new BBox(ax, ay, bx, by);
-
-		Collection<Node> allNodes = platform.getDataSet().getNodes();
-		for (Node currentNode : allNodes) {
-			if (platformBBox.bounds(currentNode.getBBox()) && currentNode.hasTag("public_transport", "stop_position")) {
-				potentialStopPositions.add(currentNode);
-			}
-		}
-
-		return potentialStopPositions;
-	}
-
-	/**
-	 * Checks if this stop equals to other by comparing if they have the same
-	 * stop_position or a platform
-	 * 
-	 * @param other
-	 *            PTStop to be compared
-	 * @return true if equal, false otherwise
-	 */
-	public boolean equalsStop(PTStop other) {
-
-		if (other == null) {
-			return false;
-		}
-
-		if (this.stopPosition != null
-				&& (this.stopPosition == other.getStopPosition() || this.stopPosition == other.getPlatform())) {
-			return true;
-		}
-
-		if (this.platform != null
-				&& (this.platform == other.getPlatform() || this.platform == other.getStopPosition())) {
-			return true;
-		}
-
-		return false;
-	}
+    /* stop_position element of this stop */
+    private Node stopPosition = null;
+
+    /* platform element of this stop */
+    private OsmPrimitive platform = null;
+
+    /* the name of this stop */
+    private String name = "";
+
+    /**
+     * Constructor
+     *
+     * @param other other relation member
+     * @throws IllegalArgumentException
+     *             if the given relation member does not fit to the data model
+     *             used in the plugin
+     */
+    public PTStop(RelationMember other) throws IllegalArgumentException {
+
+        super(other);
+
+        // if ((other.hasRole("stop") || other.hasRole("stop_entry_only") ||
+        // other.hasRole("stop_exit_only"))
+        // && other.getType().equals(OsmPrimitiveType.NODE)) {
+
+        if (other.getMember().hasTag("public_transport", "stop_position")) {
+
+            this.stopPosition = other.getNode();
+            this.name = stopPosition.get("name");
+
+            // } else if (other.getRole().equals("platform") ||
+            // other.getRole().equals("platform_entry_only")
+            // || other.getRole().equals("platform_exit_only")) {
+        } else if (other.getMember().hasTag("highway", "bus_stop")
+                || other.getMember().hasTag("public_transport", "platform")
+                || other.getMember().hasTag("highway", "platform") || other.getMember().hasTag("railway", "platform")) {
+
+            this.platform = other.getMember();
+            this.name = platform.get("name");
+
+        } else {
+            throw new IllegalArgumentException(
+                    "The RelationMember type does not match its role " + other.getMember().getName());
+        }
+
+    }
+
+    /**
+     * Adds the given element to the stop after a check
+     *
+     * @param member
+     *            Element to add
+     * @return true if added successfully, false otherwise. A false value
+     *         indicates either that the OsmPrimitiveType of the given
+     *         RelationMember does not match its role or that this PTStop
+     *         already has an attribute with that role.
+     */
+    protected boolean addStopElement(RelationMember member) {
+
+        // each element is only allowed once per stop
+
+        // add stop position:
+        // if (member.hasRole("stop") || member.hasRole("stop_entry_only") ||
+        // member.hasRole("stop_exit_only")) {
+        if (member.getMember().hasTag("public_transport", "stop_position")) {
+            if (member.getType().equals(OsmPrimitiveType.NODE) && stopPosition == null) {
+                this.stopPosition = member.getNode();
+                return true;
+            }
+        }
+
+        // add platform:
+        // if (member.getRole().equals("platform") ||
+        // member.getRole().equals("platform_entry_only")
+        // || member.getRole().equals("platform_exit_only")) {
+        if (member.getMember().hasTag("highway", "bus_stop")
+                || member.getMember().hasTag("public_transport", "platform")
+                || member.getMember().hasTag("highway", "platform")
+                || member.getMember().hasTag("railway", "platform")) {
+            if (platform == null) {
+                platform = member.getMember();
+                return true;
+            }
+        }
+
+        return false;
+
+    }
+
+    /**
+     * Returns the stop_position for this PTstop. If the stop_position is not
+     * available directly, the method searches for a stop_area relation
+     *
+     * @return the stop_position for this PTstop
+     */
+    public Node getStopPosition() {
+
+        return this.stopPosition;
+    }
+
+    /**
+     * Returns platform (including platform_entry_only and platform_exit_only)
+     *
+     * @return platform (including platform_entry_only and platform_exit_only)
+     */
+    public OsmPrimitive getPlatform() {
+        return this.platform;
+    }
+
+    /**
+     * Returns the name of this stop
+     * @return the name of this stop
+     */
+    protected String getName() {
+        return this.name;
+    }
+
+    /**
+     * Sets the stop_position for this stop to the given node
+     * @param newStopPosition the stop_position for this stop to the given node
+     */
+    public void setStopPosition(Node newStopPosition) {
+
+        this.stopPosition = newStopPosition;
+
+    }
+
+    /**
+     * Finds potential stop_positions of the platform of this PTStop. It only
+     * makes sense to call this method if the stop_position attribute is null.
+     * The stop_positions are potential because they may refer to a different
+     * route, which this method does not check.
+     *
+     * @return List of potential stop_positions for this PTStop
+     */
+    public List<Node> findPotentialStopPositions() {
+
+        ArrayList<Node> potentialStopPositions = new ArrayList<>();
+
+        if (platform == null) {
+            return potentialStopPositions;
+        }
+
+        // Look for a stop position within 0.002 degrees (around 100 m) of this
+        // platform:
+
+        LatLon platformCenter = platform.getBBox().getCenter();
+        Double ax = platformCenter.getX() - 0.002;
+        Double bx = platformCenter.getX() + 0.002;
+        Double ay = platformCenter.getY() - 0.002;
+        Double by = platformCenter.getY() + 0.002;
+        BBox platformBBox = new BBox(ax, ay, bx, by);
+
+        Collection<Node> allNodes = platform.getDataSet().getNodes();
+        for (Node currentNode : allNodes) {
+            if (platformBBox.bounds(currentNode.getBBox()) && currentNode.hasTag("public_transport", "stop_position")) {
+                potentialStopPositions.add(currentNode);
+            }
+        }
+
+        return potentialStopPositions;
+    }
+
+    /**
+     * Checks if this stop equals to other by comparing if they have the same
+     * stop_position or a platform
+     *
+     * @param other
+     *            PTStop to be compared
+     * @return true if equal, false otherwise
+     */
+    public boolean equalsStop(PTStop other) {
+
+        if (other == null) {
+            return false;
+        }
+
+        if (this.stopPosition != null
+                && (this.stopPosition == other.getStopPosition() || this.stopPosition == other.getPlatform())) {
+            return true;
+        }
+
+        if (this.platform != null
+                && (this.platform == other.getPlatform() || this.platform == other.getStopPosition())) {
+            return true;
+        }
+
+        return false;
+    }
 
 }
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/data/PTWay.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/data/PTWay.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/data/PTWay.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.data;
 
@@ -11,5 +12,5 @@
 /**
  * Representation of PTWays, which can be of OsmPrimitiveType Way or Relation
- * 
+ *
  * @author darya
  *
@@ -17,148 +18,150 @@
 public class PTWay extends RelationMember {
 
-	/*
-	 * Ways that belong to this PTWay. If the corresponding relation member is
-	 * OsmPrimitiveType.WAY, this list size is 1. If the corresponding relation
-	 * member is a nested relation, the list size is >= 1.
-	 */
-	private List<Way> ways = new ArrayList<Way>();
+    /*
+     * Ways that belong to this PTWay. If the corresponding relation member is
+     * OsmPrimitiveType.WAY, this list size is 1. If the corresponding relation
+     * member is a nested relation, the list size is >= 1.
+     */
+    private List<Way> ways = new ArrayList<>();
 
-	/**
-	 * 
-	 * @param other
-	 *            the corresponding RelationMember
-	 * @throws IllegalArgumentException
-	 *             if the given relation member cannot be a PTWay due to its
-	 *             OsmPrimitiveType and/or role.
-	 */
-	public PTWay(RelationMember other) throws IllegalArgumentException {
+    /**
+     *
+     * @param other
+     *            the corresponding RelationMember
+     * @throws IllegalArgumentException
+     *             if the given relation member cannot be a PTWay due to its
+     *             OsmPrimitiveType and/or role.
+     */
+    public PTWay(RelationMember other) throws IllegalArgumentException {
 
-		super(other);
+        super(other);
 
-		if (other.getType().equals(OsmPrimitiveType.WAY)) {
-			ways.add(other.getWay());
-		} else if (other.getType().equals(OsmPrimitiveType.RELATION)) {
-			for (RelationMember rm : other.getRelation().getMembers()) {
-				if (rm.getType().equals(OsmPrimitiveType.WAY)) {
-					ways.add(rm.getWay());
-				} else {
-					throw new IllegalArgumentException(
-							"A route relation member of OsmPrimitiveType.RELATION can only have ways as members");
-				}
-			}
-		} else {
-			// the RelationMember other cannot be a OsmPrimitiveType.NODE
-			throw new IllegalArgumentException("A node cannot be used to model a public transport way");
-		}
+        if (other.getType().equals(OsmPrimitiveType.WAY)) {
+            ways.add(other.getWay());
+        } else if (other.getType().equals(OsmPrimitiveType.RELATION)) {
+            for (RelationMember rm : other.getRelation().getMembers()) {
+                if (rm.getType().equals(OsmPrimitiveType.WAY)) {
+                    ways.add(rm.getWay());
+                } else {
+                    throw new IllegalArgumentException(
+                            "A route relation member of OsmPrimitiveType.RELATION can only have ways as members");
+                }
+            }
+        } else {
+            // the RelationMember other cannot be a OsmPrimitiveType.NODE
+            throw new IllegalArgumentException("A node cannot be used to model a public transport way");
+        }
 
-	}
+    }
 
-	/**
-	 * Returns the course of this PTWay. In most cases, this list only has 1
-	 * element. In the case of nested relations in a route, the list can have
-	 * multiple elements.
-	 * 
-	 * @return
-	 */
-	public List<Way> getWays() {
-		return this.ways;
-	}
+    /**
+     * Returns the course of this PTWay. In most cases, this list only has 1
+     * element. In the case of nested relations in a route, the list can have
+     * multiple elements.
+     *
+     * @return the course of this PTWay
+     */
+    public List<Way> getWays() {
+        return this.ways;
+    }
 
-	/**
-	 * Determines if this PTWay is modeled by an OsmPrimitiveType.WAY
-	 */
-	public boolean isWay() {
-		if (this.getType().equals(OsmPrimitiveType.WAY)) {
-			return true;
-		}
-		return false;
-	}
+    /**
+     * Determines if this PTWay is modeled by an OsmPrimitiveType.WAY
+     */
+    @Override
+    public boolean isWay() {
+        if (this.getType().equals(OsmPrimitiveType.WAY)) {
+            return true;
+        }
+        return false;
+    }
 
-	/**
-	 * Determines if this PTWay is modeled by an OsmPrimitieType.RELATION (i.e.
-	 * this is a nested relation)
-	 */
-	public boolean isRelation() {
-		if (this.getType().equals(OsmPrimitiveType.RELATION)) {
-			return true;
-		}
-		return false;
-	}
+    /**
+     * Determines if this PTWay is modeled by an OsmPrimitieType.RELATION (i.e.
+     * this is a nested relation)
+     */
+    @Override
+    public boolean isRelation() {
+        if (this.getType().equals(OsmPrimitiveType.RELATION)) {
+            return true;
+        }
+        return false;
+    }
 
-	/**
-	 * Returns the end nodes of this PTWay. If this PTWay is a nested relation,
-	 * the order of the composing ways is assumed to be correct
-	 * 
-	 * @return
-	 */
-	public Node[] getEndNodes() {
-		Node[] endNodes = new Node[2];
+    /**
+     * Returns the end nodes of this PTWay. If this PTWay is a nested relation,
+     * the order of the composing ways is assumed to be correct
+     *
+     * @return the end nodes of this PTWay
+     */
+    public Node[] getEndNodes() {
+        Node[] endNodes = new Node[2];
 
-		if (this.isWay()) {
-			endNodes[0] = this.getWay().firstNode();
-			endNodes[1] = this.getWay().lastNode();
-			// TODO: if this is a roundabout
-		} else { // nested relation:
-			Way firstWay = this.getWays().get(0);
-			Way secondWay = this.getWays().get(1);
-			Way prelastWay = this.getWays().get(this.getWays().size() - 2);
-			Way lastWay = this.getWays().get(this.getWays().size() - 1);
-			if (firstWay.firstNode() == secondWay.firstNode() || firstWay.firstNode() == secondWay.lastNode()) {
-				endNodes[0] = firstWay.lastNode();
-			} else {
-				endNodes[0] = firstWay.firstNode();
-			}
-			if (lastWay.firstNode() == prelastWay.firstNode() || lastWay.firstNode() == prelastWay.lastNode()) {
-				endNodes[1] = lastWay.lastNode();
-			} else {
-				endNodes[1] = lastWay.firstNode();
-			}
-		}
+        if (this.isWay()) {
+            endNodes[0] = this.getWay().firstNode();
+            endNodes[1] = this.getWay().lastNode();
+            // TODO: if this is a roundabout
+        } else { // nested relation:
+            Way firstWay = this.getWays().get(0);
+            Way secondWay = this.getWays().get(1);
+            Way prelastWay = this.getWays().get(this.getWays().size() - 2);
+            Way lastWay = this.getWays().get(this.getWays().size() - 1);
+            if (firstWay.firstNode() == secondWay.firstNode() || firstWay.firstNode() == secondWay.lastNode()) {
+                endNodes[0] = firstWay.lastNode();
+            } else {
+                endNodes[0] = firstWay.firstNode();
+            }
+            if (lastWay.firstNode() == prelastWay.firstNode() || lastWay.firstNode() == prelastWay.lastNode()) {
+                endNodes[1] = lastWay.lastNode();
+            } else {
+                endNodes[1] = lastWay.firstNode();
+            }
+        }
 
-		return endNodes;
-	}
+        return endNodes;
+    }
 
-	/**
-	 * Checks if this PTWay contains an unsplit roundabout (i.e. a way that
-	 * touches itself) among its ways
-	 * 
-	 * @return
-	 */
-	public boolean containsUnsplitRoundabout() {
+    /**
+     * Checks if this PTWay contains an unsplit roundabout (i.e. a way that
+     * touches itself) among its ways
+     *
+     * @return {@code true} if this PTWay contains an unsplit roundabout
+     */
+    public boolean containsUnsplitRoundabout() {
 
-		List<Way> ways = this.getWays();
-		for (Way way : ways) {
-			if (way.firstNode() == way.lastNode()) {
-				return true;
-			}
-		}
-		return false;
-	}
+        List<Way> ways = this.getWays();
+        for (Way way : ways) {
+            if (way.firstNode() == way.lastNode()) {
+                return true;
+            }
+        }
+        return false;
+    }
 
-	/**
-	 * Checks if the first Way of this PTWay is an unsplit roundabout (i.e. a
-	 * way that touches itself)
-	 * 
-	 * @return
-	 */
-	public boolean startsWithUnsplitRoundabout() {
-		if (this.ways.get(0).firstNode() == this.ways.get(0).lastNode()) {
-			return true;
-		}
-		return false;
-	}
+    /**
+     * Checks if the first Way of this PTWay is an unsplit roundabout (i.e. a
+     * way that touches itself)
+     *
+     * @return {@code true} if the first Way of this PTWay is an unsplit roundabout
+     */
+    public boolean startsWithUnsplitRoundabout() {
+        if (this.ways.get(0).firstNode() == this.ways.get(0).lastNode()) {
+            return true;
+        }
+        return false;
+    }
 
-	/**
-	 * Checks if the last Way of this PTWay is an unsplit roundabout (i.e. a way
-	 * that touches itself)
-	 * 
-	 * @return
-	 */
-	public boolean endsWithUnsplitRoundabout() {
-		if (this.ways.get(this.ways.size() - 1).firstNode() == this.ways.get(this.ways.size() - 1).lastNode()) {
-			return true;
-		}
-		return false;
-	}
+    /**
+     * Checks if the last Way of this PTWay is an unsplit roundabout (i.e. a way
+     * that touches itself)
+     *
+     * @return {@code true} if the last Way of this PTWay is an unsplit roundabout
+     */
+    public boolean endsWithUnsplitRoundabout() {
+        if (this.ways.get(this.ways.size() - 1).firstNode() == this.ways.get(this.ways.size() - 1).lastNode()) {
+            return true;
+        }
+        return false;
+    }
 
 }
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/DownloadReferrersDialog.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/DownloadReferrersDialog.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/DownloadReferrersDialog.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.gui;
 
@@ -14,64 +15,62 @@
 public class DownloadReferrersDialog extends JPanel {
 
-	private static final long serialVersionUID = 6112230984193215297L;
-	
-	// indicates if the user needs to be asked before fetching incomplete
-	// members of a relation.
-	private enum ASK_TO_FETCH {
-		DO_ASK, DONT_ASK_AND_FETCH, DONT_ASK_AND_DONT_FETCH
-	};
+    private static final long serialVersionUID = 6112230984193215297L;
 
-	// by default, the user should be asked
-	private static ASK_TO_FETCH askToFetch = ASK_TO_FETCH.DO_ASK;
+    // indicates if the user needs to be asked before fetching incomplete
+    // members of a relation.
+    private enum ASK_TO_FETCH {
+        DO_ASK, DONT_ASK_AND_FETCH, DONT_ASK_AND_DONT_FETCH
+    }
 
-	String message;
-	private JCheckBox checkbox;
-	private String[] options;
-	private int selectedOption;
+    // by default, the user should be asked
+    private static ASK_TO_FETCH askToFetch = ASK_TO_FETCH.DO_ASK;
 
-	public DownloadReferrersDialog() {
-		
-		selectedOption = Integer.MIN_VALUE;
-		message = tr("Do you want to download referrers of platforms and stop positions?");
-		checkbox = new JCheckBox(tr("Remember my choice and do not ask me again in this session"));
-		options = new String[2];
-		options[0] = tr("Yes");
-		options[1] = tr("No");
+    String message;
+    private JCheckBox checkbox;
+    private String[] options;
+    private int selectedOption;
 
-	}
+    public DownloadReferrersDialog() {
 
-	/**
-	 * Finds out whether the user wants to download referrers. In the
-	 * default case, creates a JOptionPane to ask.
-	 * 
-	 * @return JOptionPane.YES_OPTION if the referrers should be
-	 *         downloaded, JOptionPane.NO_OPTION otherwise.
-	 */
-	public int getUserSelection() {
+        selectedOption = Integer.MIN_VALUE;
+        message = tr("Do you want to download referrers of platforms and stop positions?");
+        checkbox = new JCheckBox(tr("Remember my choice and do not ask me again in this session"));
+        options = new String[2];
+        options[0] = tr("Yes");
+        options[1] = tr("No");
 
-		if (askToFetch == ASK_TO_FETCH.DONT_ASK_AND_FETCH) {
-			return JOptionPane.YES_OPTION;
-		}
+    }
 
-		if (askToFetch == ASK_TO_FETCH.DONT_ASK_AND_DONT_FETCH) {
-			return JOptionPane.NO_OPTION;
-		}
+    /**
+     * Finds out whether the user wants to download referrers. In the
+     * default case, creates a JOptionPane to ask.
+     *
+     * @return JOptionPane.YES_OPTION if the referrers should be
+     *         downloaded, JOptionPane.NO_OPTION otherwise.
+     */
+    public int getUserSelection() {
 
-		
-		Object[] params = {message, checkbox};
-		selectedOption = JOptionPane.showOptionDialog(this, params, tr("PT_Assistant Fetch Request"), JOptionPane.YES_NO_OPTION,
-				JOptionPane.QUESTION_MESSAGE, null, options, 0);
-		
-		if (checkbox.isSelected()) {
-			if (selectedOption == JOptionPane.YES_OPTION) {
-				askToFetch = ASK_TO_FETCH.DONT_ASK_AND_FETCH;
-			} else {
-				askToFetch = ASK_TO_FETCH.DONT_ASK_AND_DONT_FETCH;
-			}
-		}
+        if (askToFetch == ASK_TO_FETCH.DONT_ASK_AND_FETCH) {
+            return JOptionPane.YES_OPTION;
+        }
 
-		return selectedOption;
-	}
+        if (askToFetch == ASK_TO_FETCH.DONT_ASK_AND_DONT_FETCH) {
+            return JOptionPane.NO_OPTION;
+        }
 
 
+        Object[] params = {message, checkbox};
+        selectedOption = JOptionPane.showOptionDialog(this, params, tr("PT_Assistant Fetch Request"), JOptionPane.YES_NO_OPTION,
+                JOptionPane.QUESTION_MESSAGE, null, options, 0);
+
+        if (checkbox.isSelected()) {
+            if (selectedOption == JOptionPane.YES_OPTION) {
+                askToFetch = ASK_TO_FETCH.DONT_ASK_AND_FETCH;
+            } else {
+                askToFetch = ASK_TO_FETCH.DONT_ASK_AND_DONT_FETCH;
+            }
+        }
+
+        return selectedOption;
+    }
 }
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/IncompleteMembersDownloadDialog.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/IncompleteMembersDownloadDialog.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/IncompleteMembersDownloadDialog.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.gui;
 
@@ -10,5 +11,5 @@
  * Dialog that asks the user whether the incomplete relation members should be
  * downloaded.
- * 
+ *
  * @author darya
  *
@@ -16,63 +17,63 @@
 public class IncompleteMembersDownloadDialog extends JPanel {
 
-	private static final long serialVersionUID = -4275151182361040329L;
+    private static final long serialVersionUID = -4275151182361040329L;
 
-	// indicates if the user needs to be asked before fetching incomplete
-	// members of a relation.
-	public enum ASK_TO_FETCH {
-		DO_ASK, DONT_ASK_AND_FETCH, DONT_ASK_AND_DONT_FETCH
-	};
+    // indicates if the user needs to be asked before fetching incomplete
+    // members of a relation.
+    public enum ASK_TO_FETCH {
+        DO_ASK, DONT_ASK_AND_FETCH, DONT_ASK_AND_DONT_FETCH
+    }
 
-	// by default, the user should be asked
-	public static ASK_TO_FETCH askToFetch;
+    // by default, the user should be asked
+    public static ASK_TO_FETCH askToFetch;
 
-	String message;
-	private JCheckBox checkbox;
-	private String[] options;
-	private int selectedOption;
+    String message;
+    private JCheckBox checkbox;
+    private String[] options;
+    private int selectedOption;
 
-	public IncompleteMembersDownloadDialog() {
+    public IncompleteMembersDownloadDialog() {
 
-		selectedOption = Integer.MIN_VALUE;
-		message = tr(
-				"Route relations have incomplete members.\nThey need to be downloaded to proceed with validation.\nDo you want to download them?");
-		checkbox = new JCheckBox(tr("Remember my choice and do not ask me again in this session"));
-		options = new String[2];
-		options[0] = tr("Yes");
-		options[1] = tr("No");
+        selectedOption = Integer.MIN_VALUE;
+        message = tr(
+            "Route relations have incomplete members.\nThey need to be downloaded to proceed with validation.\nDo you want to download them?");
+        checkbox = new JCheckBox(tr("Remember my choice and do not ask me again in this session"));
+        options = new String[2];
+        options[0] = tr("Yes");
+        options[1] = tr("No");
 
-	}
+    }
 
-	/**
-	 * Finds out whether the user wants to download incomplete members. In the
-	 * default case, creates a JOptionPane to ask.
-	 * 
-	 * @return JOptionPane.YES_OPTION if the incomplete members should be
-	 *         downloaded, JOptionPane.NO_OPTION otherwise.
-	 */
-	public int getUserSelection() {
+    /**
+     * Finds out whether the user wants to download incomplete members. In the
+     * default case, creates a JOptionPane to ask.
+     *
+     * @return JOptionPane.YES_OPTION if the incomplete members should be
+     *         downloaded, JOptionPane.NO_OPTION otherwise.
+     */
+    public int getUserSelection() {
 
-		if (askToFetch == ASK_TO_FETCH.DONT_ASK_AND_FETCH) {
-			return JOptionPane.YES_OPTION;
-		}
+        if (askToFetch == ASK_TO_FETCH.DONT_ASK_AND_FETCH) {
+            return JOptionPane.YES_OPTION;
+        }
 
-		if (askToFetch == ASK_TO_FETCH.DONT_ASK_AND_DONT_FETCH) {
-			return JOptionPane.NO_OPTION;
-		}
+        if (askToFetch == ASK_TO_FETCH.DONT_ASK_AND_DONT_FETCH) {
+            return JOptionPane.NO_OPTION;
+        }
 
-		Object[] params = { message, checkbox };
-		selectedOption = JOptionPane.showOptionDialog(this, params, tr("PT_Assistant Fetch Request"),
-				JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, 0);
+        Object[] params = {message, checkbox};
+        selectedOption = JOptionPane.showOptionDialog(this, params, tr("PT_Assistant Fetch Request"),
+                JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, 0);
 
-		if (checkbox.isSelected()) {
-			if (selectedOption == JOptionPane.YES_OPTION) {
-				askToFetch = ASK_TO_FETCH.DONT_ASK_AND_FETCH;
-			} else {
-				askToFetch = ASK_TO_FETCH.DONT_ASK_AND_DONT_FETCH;
-			}
-		}
+        if (checkbox.isSelected()) {
+            if (selectedOption == JOptionPane.YES_OPTION) {
+                askToFetch = ASK_TO_FETCH.DONT_ASK_AND_FETCH;
+            } else {
+                askToFetch = ASK_TO_FETCH.DONT_ASK_AND_DONT_FETCH;
+            }
+        }
 
-		return selectedOption;
-	}
+        return selectedOption;
+    }
 
 }
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 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/PTAssistantLayer.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.gui;
 
@@ -40,259 +41,259 @@
 /**
  * Layer that visualizes the routes in a more convenient way
- * 
+ *
  * @author darya
  *
  */
-public class PTAssistantLayer extends Layer
-		implements SelectionChangedListener, PropertyChangeListener, LayerChangeListener {
-
-	private static PTAssistantLayer layer;
-	private List<OsmPrimitive> primitives = new ArrayList<>();
-	private PTAssistantPaintVisitor paintVisitor;
-	private HashMap<Character, List<PTWay>> fixVariants = new HashMap<>();
-	private HashMap<Way, List<Character>> wayColoring = new HashMap<>();
-
-	private PTAssistantLayer() {
-		super("pt_assistant layer");
-		KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener(this);
-		Main.getLayerManager().addLayerChangeListener(this);
-		layer = this;
-	}
-
-	public static PTAssistantLayer getLayer() {
-		if (layer == null) {
-			new PTAssistantLayer();
-		}
-		return layer;
-	}
-
-	/**
-	 * Adds a primitive (route) to be displayed in this layer
-	 * 
-	 * @param primitive
-	 */
-	public void addPrimitive(OsmPrimitive primitive) {
-		this.primitives.add(primitive);
-	}
-
-	/**
-	 * Clears all primitives (routes) from being displayed.
-	 */
-	public void clear() {
-		this.primitives.clear();
-	}
-
-	public void clearFixVariants() {
-		fixVariants.clear();
-		wayColoring.clear();
-		Main.map.mapView.repaint();
-	}
-
-	/**
-	 * Adds the first 5 fix variants to be displayed in the pt_assistant layer
-	 * 
-	 * @param fixVariants
-	 */
-	public void addFixVariants(List<List<PTWay>> fixVariants) {
-		HashMap<List<PTWay>, Character> fixVariantLetterMap = new HashMap<>();
-
-		char alphabet = 'A';
-		for (int i = 0; i < 5 && i < fixVariants.size(); i++) {
-			List<PTWay> fixVariant = fixVariants.get(i);
-			this.fixVariants.put(alphabet, fixVariant);
-			fixVariantLetterMap.put(fixVariant, alphabet);
-			alphabet++;
-		}
-
-		for (Character currentFixVariantLetter : this.fixVariants.keySet()) {
-			List<PTWay> fixVariant = this.fixVariants.get(currentFixVariantLetter);
-			for (PTWay ptway : fixVariant) {
-				for (Way way : ptway.getWays()) {
-					if (wayColoring.containsKey(way)) {
-						if (!wayColoring.get(way).contains(currentFixVariantLetter)) {
-							wayColoring.get(way).add(currentFixVariantLetter);
-						}
-					} else {
-						List<Character> letterList = new ArrayList<>();
-						letterList.add(currentFixVariantLetter);
-						wayColoring.put(way, letterList);
-					}
-				}
-			}
-		}
-	}
-
-	/**
-	 * Returns fix variant (represented by a list of PTWays) that corresponds to
-	 * the given character.
-	 * 
-	 * @param c
-	 * @return
-	 */
-	public List<PTWay> getFixVariant(char c) {
-		return this.fixVariants.get(Character.toUpperCase(c));
-	}
-
-	@Override
-	public void paint(final Graphics2D g, final MapView mv, Bounds bounds) {
-
-		paintVisitor = new PTAssistantPaintVisitor(g, mv);
-
-		for (OsmPrimitive primitive : primitives) {
-			paintVisitor.visit(primitive);
-		}
-
-		paintVisitor.visitFixVariants(this.fixVariants, this.wayColoring);
-
-	}
-
-	@Override
-	public Icon getIcon() {
-		return ImageProvider.get("layer", "osmdata_small");
-	}
-
-	@Override
-	public Object getInfoComponent() {
-		return getToolTipText();
-	}
-
-	@Override
-	public Action[] getMenuEntries() {
-		return new Action[] { LayerListDialog.getInstance().createShowHideLayerAction(),
-				LayerListDialog.getInstance().createDeleteLayerAction(), SeparatorLayerAction.INSTANCE,
-				new RenameLayerAction(null, this), SeparatorLayerAction.INSTANCE, new LayerListPopup.InfoAction(this) };
-	}
-
-	@Override
-	public String getToolTipText() {
-		return "pt_assistant layer";
-	}
-
-	@Override
-	public boolean isMergable(Layer arg0) {
-		return false;
-	}
-
-	@Override
-	public void mergeFrom(Layer arg0) {
-		// do nothing
-
-	}
-
-	@Override
-	public void visitBoundingBox(BoundingXYVisitor arg0) {
-		// do nothing
-
-	}
-
-	@Override
-	public LayerPositionStrategy getDefaultLayerPosition() {
-		return LayerPositionStrategy.IN_FRONT;
-	}
-
-	/**
-	 * Listens to a selection change
-	 */
-	@Override
-	public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
-
-		ArrayList<Relation> routes = new ArrayList<>();
-
-		for (OsmPrimitive primitive : newSelection) {
-			if (primitive.getType().equals(OsmPrimitiveType.RELATION)) {
-				Relation relation = (Relation) primitive;
-				if (RouteUtils.isTwoDirectionRoute(relation)) {
-					routes.add(relation);
-				}
-
-			}
-		}
-
-		if (!routes.isEmpty()) {
-			this.primitives.clear();
-			this.primitives.addAll(routes);
-			if (!Main.getLayerManager().containsLayer(this)) {
-				Main.getLayerManager().addLayer(this);
-			}
-		}
-
-	}
-
-	/**
-	 * Listens to a focus change, sets the primitives attribute to the route
-	 * relation in the top Relation Editor and repaints the map
-	 */
-	@Override
-	public void propertyChange(PropertyChangeEvent evt) {
-
-		if ("focusedWindow".equals(evt.getPropertyName())) {
-
-			if (evt.getNewValue() == null) {
-				return;
-			}
-
-			if (evt.getNewValue().getClass().equals(GenericRelationEditor.class)) {
-
-				GenericRelationEditor editor = (GenericRelationEditor) evt.getNewValue();
-				Relation relation = editor.getRelation();
-
-				if (RouteUtils.isTwoDirectionRoute(relation)) {
-
-					this.repaint(relation);
-
-				}
-
-			}
-		}
-	}
-
-	/**
-	 * Repaints the layer in cases when there was no selection change
-	 * 
-	 * @param relation
-	 */
-	public void repaint(Relation relation) {
-		this.primitives.clear();
-		this.primitives.add(relation);
-		if (!Main.getLayerManager().containsLayer(this)) {
-			Main.getLayerManager().addLayer(this);
-		}
-
-		if (paintVisitor == null) {
-			Graphics g = Main.map.mapView.getGraphics();
-			MapView mv = Main.map.mapView;
-			paintVisitor = new PTAssistantPaintVisitor(g, mv);
-		}
-
-		for (OsmPrimitive primitive : primitives) {
-			paintVisitor.visit(primitive);
-		}
-
-		paintVisitor.visitFixVariants(this.fixVariants, this.wayColoring);
-
-		Main.map.mapView.repaint();
-	}
-
-	@Override
-	public void layerAdded(LayerAddEvent arg0) {
-		// do nothing
-	}
-
-	@Override
-	public void layerOrderChanged(LayerOrderChangeEvent arg0) {
-		// do nothing
-
-	}
-
-	@Override
-	public void layerRemoving(LayerRemoveEvent event) {
-
-		if (event.getRemovedLayer() instanceof OsmDataLayer) {
-			this.primitives.clear();
-			this.fixVariants.clear();
-			this.wayColoring.clear();
-			Main.map.mapView.repaint();
-		}
-
-	}
+public final class PTAssistantLayer extends Layer
+        implements SelectionChangedListener, PropertyChangeListener, LayerChangeListener {
+
+    private static PTAssistantLayer layer;
+    private List<OsmPrimitive> primitives = new ArrayList<>();
+    private PTAssistantPaintVisitor paintVisitor;
+    private HashMap<Character, List<PTWay>> fixVariants = new HashMap<>();
+    private HashMap<Way, List<Character>> wayColoring = new HashMap<>();
+
+    private PTAssistantLayer() {
+        super("pt_assistant layer");
+        KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener(this);
+        Main.getLayerManager().addLayerChangeListener(this);
+        layer = this;
+    }
+
+    public static PTAssistantLayer getLayer() {
+        if (layer == null) {
+            new PTAssistantLayer();
+        }
+        return layer;
+    }
+
+    /**
+     * Adds a primitive (route) to be displayed in this layer
+     *
+     * @param primitive primitive (route)
+     */
+    public void addPrimitive(OsmPrimitive primitive) {
+        this.primitives.add(primitive);
+    }
+
+    /**
+     * Clears all primitives (routes) from being displayed.
+     */
+    public void clear() {
+        this.primitives.clear();
+    }
+
+    public void clearFixVariants() {
+        fixVariants.clear();
+        wayColoring.clear();
+        Main.map.mapView.repaint();
+    }
+
+    /**
+     * Adds the first 5 fix variants to be displayed in the pt_assistant layer
+     *
+     * @param fixVariants fix variants
+     */
+    public void addFixVariants(List<List<PTWay>> fixVariants) {
+        HashMap<List<PTWay>, Character> fixVariantLetterMap = new HashMap<>();
+
+        char alphabet = 'A';
+        for (int i = 0; i < 5 && i < fixVariants.size(); i++) {
+            List<PTWay> fixVariant = fixVariants.get(i);
+            this.fixVariants.put(alphabet, fixVariant);
+            fixVariantLetterMap.put(fixVariant, alphabet);
+            alphabet++;
+        }
+
+        for (Character currentFixVariantLetter : this.fixVariants.keySet()) {
+            List<PTWay> fixVariant = this.fixVariants.get(currentFixVariantLetter);
+            for (PTWay ptway : fixVariant) {
+                for (Way way : ptway.getWays()) {
+                    if (wayColoring.containsKey(way)) {
+                        if (!wayColoring.get(way).contains(currentFixVariantLetter)) {
+                            wayColoring.get(way).add(currentFixVariantLetter);
+                        }
+                    } else {
+                        List<Character> letterList = new ArrayList<>();
+                        letterList.add(currentFixVariantLetter);
+                        wayColoring.put(way, letterList);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns fix variant (represented by a list of PTWays) that corresponds to
+     * the given character.
+     *
+     * @param c character
+     * @return fix variant
+     */
+    public List<PTWay> getFixVariant(char c) {
+        return this.fixVariants.get(Character.toUpperCase(c));
+    }
+
+    @Override
+    public void paint(final Graphics2D g, final MapView mv, Bounds bounds) {
+
+        paintVisitor = new PTAssistantPaintVisitor(g, mv);
+
+        for (OsmPrimitive primitive : primitives) {
+            paintVisitor.visit(primitive);
+        }
+
+        paintVisitor.visitFixVariants(this.fixVariants, this.wayColoring);
+
+    }
+
+    @Override
+    public Icon getIcon() {
+        return ImageProvider.get("layer", "osmdata_small");
+    }
+
+    @Override
+    public Object getInfoComponent() {
+        return getToolTipText();
+    }
+
+    @Override
+    public Action[] getMenuEntries() {
+        return new Action[] {LayerListDialog.getInstance().createShowHideLayerAction(),
+                LayerListDialog.getInstance().createDeleteLayerAction(), SeparatorLayerAction.INSTANCE,
+                new RenameLayerAction(null, this), SeparatorLayerAction.INSTANCE, new LayerListPopup.InfoAction(this)};
+    }
+
+    @Override
+    public String getToolTipText() {
+        return "pt_assistant layer";
+    }
+
+    @Override
+    public boolean isMergable(Layer arg0) {
+        return false;
+    }
+
+    @Override
+    public void mergeFrom(Layer arg0) {
+        // do nothing
+
+    }
+
+    @Override
+    public void visitBoundingBox(BoundingXYVisitor arg0) {
+        // do nothing
+
+    }
+
+    @Override
+    public LayerPositionStrategy getDefaultLayerPosition() {
+        return LayerPositionStrategy.IN_FRONT;
+    }
+
+    /**
+     * Listens to a selection change
+     */
+    @Override
+    public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
+
+        ArrayList<Relation> routes = new ArrayList<>();
+
+        for (OsmPrimitive primitive : newSelection) {
+            if (primitive.getType().equals(OsmPrimitiveType.RELATION)) {
+                Relation relation = (Relation) primitive;
+                if (RouteUtils.isTwoDirectionRoute(relation)) {
+                    routes.add(relation);
+                }
+
+            }
+        }
+
+        if (!routes.isEmpty()) {
+            this.primitives.clear();
+            this.primitives.addAll(routes);
+            if (!Main.getLayerManager().containsLayer(this)) {
+                Main.getLayerManager().addLayer(this);
+            }
+        }
+
+    }
+
+    /**
+     * Listens to a focus change, sets the primitives attribute to the route
+     * relation in the top Relation Editor and repaints the map
+     */
+    @Override
+    public void propertyChange(PropertyChangeEvent evt) {
+
+        if ("focusedWindow".equals(evt.getPropertyName())) {
+
+            if (evt.getNewValue() == null) {
+                return;
+            }
+
+            if (evt.getNewValue().getClass().equals(GenericRelationEditor.class)) {
+
+                GenericRelationEditor editor = (GenericRelationEditor) evt.getNewValue();
+                Relation relation = editor.getRelation();
+
+                if (RouteUtils.isTwoDirectionRoute(relation)) {
+
+                    this.repaint(relation);
+
+                }
+
+            }
+        }
+    }
+
+    /**
+     * Repaints the layer in cases when there was no selection change
+     *
+     * @param relation relation
+     */
+    public void repaint(Relation relation) {
+        this.primitives.clear();
+        this.primitives.add(relation);
+        if (!Main.getLayerManager().containsLayer(this)) {
+            Main.getLayerManager().addLayer(this);
+        }
+
+        if (paintVisitor == null) {
+            Graphics g = Main.map.mapView.getGraphics();
+            MapView mv = Main.map.mapView;
+            paintVisitor = new PTAssistantPaintVisitor(g, mv);
+        }
+
+        for (OsmPrimitive primitive : primitives) {
+            paintVisitor.visit(primitive);
+        }
+
+        paintVisitor.visitFixVariants(this.fixVariants, this.wayColoring);
+
+        Main.map.mapView.repaint();
+    }
+
+    @Override
+    public void layerAdded(LayerAddEvent arg0) {
+        // do nothing
+    }
+
+    @Override
+    public void layerOrderChanged(LayerOrderChangeEvent arg0) {
+        // do nothing
+
+    }
+
+    @Override
+    public void layerRemoving(LayerRemoveEvent event) {
+
+        if (event.getRemovedLayer() instanceof OsmDataLayer) {
+            this.primitives.clear();
+            this.fixVariants.clear();
+            this.wayColoring.clear();
+            Main.map.mapView.repaint();
+        }
+
+    }
 }
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 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/PTAssistantPaintVisitor.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.gui;
 
@@ -27,5 +28,5 @@
 /**
  * Visits the primitives to be visualized in the pt_assistant layer
- * 
+ *
  * @author darya
  *
@@ -33,564 +34,557 @@
 public class PTAssistantPaintVisitor extends PaintVisitor {
 
-	/** The graphics */
-	private final Graphics g;
-	/** The MapView */
-	private final MapView mv;
-
-	/**
-	 * Constructor
-	 * 
-	 * @param g
-	 * @param mv
-	 */
-	public PTAssistantPaintVisitor(Graphics g, MapView mv) {
-		super(g, mv);
-		this.g = g;
-		this.mv = mv;
-	}
-
-	@Override
-	public void visit(Relation r) {
-
-		// first, draw primitives:
-		for (RelationMember rm : r.getMembers()) {
-
-			if (RouteUtils.isPTStop(rm)) {
-
-				drawStop(rm.getMember());
-
-			} else if (RouteUtils.isPTWay(rm)) {
-				if (rm.isWay()) {
-					visit(rm.getWay());
-				} else if (rm.isRelation()) {
-					visit(rm.getRelation());
-				} else {
-					// if the relation has members that do not fit with the
-					// PT_Assistant data model, do nothing
-				}
-			} else {
-				// if the relation has members that do not fit with the
-				// PT_Assistant data model, do nothing
-			}
-		}
-
-		// in the end, draw labels:
-		HashMap<Long, String> stopOrderMap = new HashMap<>();
-		int stopCount = 1;
-
-		for (RelationMember rm : r.getMembers()) {
-			if (RouteUtils.isPTStop(rm) || (rm.getMember().isIncomplete() && (rm.isNode() || rm.hasRole("stop")
-					|| rm.hasRole("stop_entry_only") || rm.hasRole("stop_exit_only") || rm.hasRole("platform")
-					|| rm.hasRole("platform_entry_only") || rm.hasRole("platform_exit_only")))) {
-
-				String label = "";
-
-				if (stopOrderMap.containsKey(rm.getUniqueId())) {
-					label = stopOrderMap.get(rm.getUniqueId());
-					label = label + ";" + stopCount;
-				} else {
-					if (r.hasKey("ref")) {
-						label = label + r.get("ref");
-					} else if (r.hasKey("name")) {
-						label = label + r.get("name");
-					} else {
-						label = "NA";
-					}
-					label = label + " - " + stopCount;
-				}
-
-				stopOrderMap.put(rm.getUniqueId(), label);
-				try {
-					drawStopLabel(rm.getMember(), label);
-				} catch (NullPointerException ex) {
-					// do nothing
-				}
-				stopCount++;
-			}
-		}
-
-	}
-
-	@Override
-	public void visit(Way w) {
-
-		if (w == null) {
-			return;
-		}
-
-		/*-
-		 * oneway values:
-		 * 0 two-way street
-		 * 1 oneway street in the way's direction
-		 * 2 oneway street in ways's direction but public transport allowed
-		 * -1 oneway street in reverse direction
-		 * -2 oneway street in reverse direction but public transport allowed
-		 */
-		int oneway = 0;
-
-		if (w.hasTag("junction", "roundabout") || w.hasTag("highway", "motorway")) {
-			oneway = 1;
-		} else if (w.hasTag("oneway", "1") || w.hasTag("oneway", "yes") || w.hasTag("oneway", "true")) {
-			if (w.hasTag("busway", "lane") || w.hasTag("busway:left", "lane") || w.hasTag("busway:right", "lane")
-					|| w.hasTag("oneway:bus", "no") || w.hasTag("busway", "opposite_lane")
-					|| w.hasTag("oneway:psv", "no") || w.hasTag("trolley_wire", "backward")) {
-				oneway = 2;
-			} else {
-				oneway = 1;
-			}
-		} else if (w.hasTag("oneway", "-1") || w.hasTag("oneway", "reverse")) {
-			if (w.hasTag("busway", "lane") || w.hasTag("busway:left", "lane") || w.hasTag("busway:right", "lane")
-					|| w.hasTag("oneway:bus", "no") || w.hasTag("busway", "opposite_lane")
-					|| w.hasTag("oneway:psv", "no") || w.hasTag("trolley_wire", "backward")) {
-				oneway = -2;
-			} else {
-				oneway = -1;
-			}
-		}
-
-		visit(w.getNodes(), oneway);
-
-	}
-
-	/**
-	 * Variation of the visit method that allows a special visualization of
-	 * oneway roads
-	 * 
-	 * @param nodes
-	 * @param oneway
-	 */
-	public void visit(List<Node> nodes, int oneway) {
-		Node lastN = null;
-		for (Node n : nodes) {
-			if (lastN == null) {
-				lastN = n;
-				continue;
-			}
-			this.drawSegment(lastN, n, new Color(128, 0, 128, 100), oneway);
-			lastN = n;
-		}
-	}
-
-	/**
-	 * Draw a small rectangle. White if selected (as always) or red otherwise.
-	 *
-	 * @param n
-	 *            The node to draw.
-	 */
-	@Override
-	public void visit(Node n) {
-		if (n.isDrawable() && isNodeVisible(n)) {
-			drawNode(n, Color.BLUE);
-		}
-	}
-
-	/**
-	 * Draws a line around the segment
-	 *
-	 * @param n1
-	 *            The first node of segment
-	 * @param n2
-	 *            The second node of segment
-	 * @param color
-	 *            The color
-	 */
-	protected void drawSegment(Node n1, Node n2, Color color, int oneway) {
-		if (n1.isDrawable() && n2.isDrawable() && isSegmentVisible(n1, n2)) {
-			try {
-				drawSegment(mv.getPoint(n1), mv.getPoint(n2), color, oneway);
-			} catch (NullPointerException ex) {
-				// do nothing
-			}
-
-		}
-	}
-
-	/**
-	 * Draws a line around the segment
-	 *
-	 * @param p1
-	 *            The first point of segment
-	 * @param p2
-	 *            The second point of segment
-	 * @param color
-	 *            The color
-	 */
-	protected void drawSegment(Point p1, Point p2, Color color, int oneway) {
-
-		double t = Math.atan2((double) p2.x - p1.x, (double) p2.y - p1.y);
-		double cosT = 9 * Math.cos(t);
-		double sinT = 9 * Math.sin(t);
-
-		int[] xPoints = { (int) (p1.x + cosT), (int) (p2.x + cosT), (int) (p2.x - cosT), (int) (p1.x - cosT) };
-		int[] yPoints = { (int) (p1.y - sinT), (int) (p2.y - sinT), (int) (p2.y + sinT), (int) (p1.y + sinT) };
-		g.setColor(color);
-		g.fillPolygon(xPoints, yPoints, 4);
-		g.fillOval((int) (p1.x - 9), (int) (p1.y - 9), 18, 18);
-		g.fillOval((int) (p2.x - 9), (int) (p2.y - 9), 18, 18);
-
-		if (oneway != 0) {
-			double middleX = (double) (p1.x + p2.x) / 2.0;
-			double middleY = (double) (p1.y + p2.y) / 2.0;
-			double cosTriangle = 6 * Math.cos(t);
-			double sinTriangle = 6 * Math.sin(t);
-			g.setColor(Color.WHITE);
-
-			if (oneway > 0) {
-				int[] xFillTriangle = { (int) (middleX + cosTriangle), (int) (middleX - cosTriangle),
-						(int) (middleX + 2 * sinTriangle) };
-				int[] yFillTriangle = { (int) (middleY - sinTriangle), (int) (middleY + sinTriangle),
-						(int) (middleY + 2 * cosTriangle) };
-				g.fillPolygon(xFillTriangle, yFillTriangle, 3);
-
-				if (oneway == 2) {
-					int[] xDrawTriangle = { (int) (middleX + cosTriangle), (int) (middleX - cosTriangle),
-							(int) (middleX - 2 * sinTriangle) };
-					int[] yDrawTriangle = { (int) (middleY - sinTriangle), (int) (middleY + sinTriangle),
-							(int) (middleY - 2 * cosTriangle) };
-					g.drawPolygon(xDrawTriangle, yDrawTriangle, 3);
-				}
-			}
-
-			if (oneway < 0) {
-				int[] xFillTriangle = { (int) (middleX + cosTriangle), (int) (middleX - cosTriangle),
-						(int) (middleX - 2 * sinTriangle) };
-				int[] yFillTriangle = { (int) (middleY - sinTriangle), (int) (middleY + sinTriangle),
-						(int) (middleY - 2 * cosTriangle) };
-				g.fillPolygon(xFillTriangle, yFillTriangle, 3);
-
-				if (oneway == -2) {
-					int[] xDrawTriangle = { (int) (middleX + cosTriangle), (int) (middleX - cosTriangle),
-							(int) (middleX + 2 * sinTriangle) };
-					int[] yDrawTriangle = { (int) (middleY - sinTriangle), (int) (middleY + sinTriangle),
-							(int) (middleY + 2 * cosTriangle) };
-					g.drawPolygon(xDrawTriangle, yDrawTriangle, 3);
-				}
-			}
-
-		}
-
-	}
-
-	/**
-	 * Draws a circle around the node
-	 * 
-	 * @param n
-	 *            The node
-	 * @param color
-	 *            The circle color
-	 */
-	protected void drawNode(Node n, Color color) {
-
-		Point p = mv.getPoint(n);
-
-		g.setColor(color);
-		g.drawOval(p.x - 5, p.y - 5, 10, 10);
-
-	}
-
-	/**
-	 * Draws s stop_position as a blue circle; draws a platform as a blue square
-	 * 
-	 * @param primitive
-	 */
-	protected void drawStop(OsmPrimitive primitive) {
-
-		// find the point to which the stop visualization will be linked:
-		Node n = new Node(primitive.getBBox().getCenter());
-
-		Point p = mv.getPoint(n);
-
-		g.setColor(Color.BLUE);
-
-		if (primitive.hasTag("public_transport", "stop_position") && p != null) {
-			g.fillOval(p.x - 8, p.y - 8, 16, 16);
-		} else {
-			g.fillRect(p.x - 8, p.y - 8, 16, 16);
-		}
-
-	}
-
-	/**
-	 * Draws the labels for the stops, which include the ordered position of the
-	 * stop in the route and the ref numbers of other routes that use this stop
-	 * 
-	 * @param primitive
-	 * @param label
-	 */
-	protected void drawStopLabel(OsmPrimitive primitive, String label) {
-
-		// find the point to which the stop visualization will be linked:
-		Node n = new Node(primitive.getBBox().getCenter());
-
-		Point p = mv.getPoint(n);
-
-		if (label != null && !label.equals("")) {
-			g.setColor(Color.WHITE);
-			Font stringFont = new Font("SansSerif", Font.PLAIN, 24);
-			g.setFont(stringFont);
-			g.drawString(label, p.x + 20, p.y - 20);
-		}
-
-		// draw the ref values of all parent routes:
-		List<String> parentsLabelList = new ArrayList<>();
-		for (OsmPrimitive parent : primitive.getReferrers()) {
-			if (parent.getType().equals(OsmPrimitiveType.RELATION)) {
-				Relation relation = (Relation) parent;
-				if (RouteUtils.isTwoDirectionRoute(relation) && relation.get("ref") != null
-						&& !relation.get("ref").equals("")) {
-
-					boolean stringFound = false;
-					for (String s : parentsLabelList) {
-						if (s.equals(relation.get("ref"))) {
-							stringFound = true;
-						}
-					}
-					if (!stringFound) {
-						parentsLabelList.add(relation.get("ref"));
-					}
-
-				}
-			}
-		}
-
-		Collections.sort(parentsLabelList, new RefTagComparator());
-
-		String parentsLabel = "";
-		for (String s : parentsLabelList) {
-			parentsLabel = parentsLabel + s + ";";
-		}
-
-		if (!parentsLabel.equals("")) {
-			// remove the last semicolon:
-			parentsLabel = parentsLabel.substring(0, parentsLabel.length() - 1);
-
-			g.setColor(new Color(255, 20, 147));
-			Font parentLabelFont = new Font("SansSerif", Font.ITALIC, 20);
-			g.setFont(parentLabelFont);
-			g.drawString(parentsLabel, p.x + 20, p.y + 20);
-		}
-
-	}
-
-	/**
-	 * Compares route ref numbers
-	 * @author darya
-	 *
-	 */
-	private class RefTagComparator implements Comparator<String> {
-
-		@Override
-		public int compare(String s1, String s2) {
-
-			if (s1 == null || s1.equals("") || s2 == null || s2.equals("")) {
-				// if at least one of the strings is null or empty, there is no
-				// point in comparing:
-				return 0;
-			}
-
-			String[] splitString1 = s1.split("\\D");
-			String[] splitString2 = s2.split("\\D");
-
-			if (splitString1.length == 0 && splitString2.length != 0) {
-				// if the first ref does not start a digit and the second ref
-				// starts with a digit:
-				return 1;
-			}
-
-			if (splitString1.length != 0 && splitString2.length == 0) {
-				// if the first ref starts a digit and the second ref does not
-				// start with a digit:
-				return -1;
-			}
-
-			if (splitString1.length == 0 && splitString2.length == 0) {
-				// if both ref values do not start with a digit:
-				return s1.compareTo(s2);
-			}
-
-			String firstNumberString1 = splitString1[0];
-			String firstNumberString2 = splitString2[0];
-
-			try {
-				int firstNumber1 = Integer.valueOf(firstNumberString1);
-				int firstNumber2 = Integer.valueOf(firstNumberString2);
-				if (firstNumber1 > firstNumber2) {
-					return 1;
-				} else if (firstNumber1 < firstNumber2) {
-					return -1;
-				} else {
-					// if the first number is the same:
-
-					return s1.compareTo(s2);
-
-				}
-			} catch (NumberFormatException ex) {
-				return s1.compareTo(s2);
-			}
-
-		}
-
-	}
-
-	/**
-	 * Visualizes the fix variants, assigns colors to them based on their order
-	 * @param fixVariants
-	 */
-	protected void visitFixVariants(HashMap<Character, List<PTWay>> fixVariants,
-			HashMap<Way, List<Character>> wayColoring) {
-
-		drawFixVariantsWithParallelLines(wayColoring, fixVariants.size());
-
-		Color[] colors = { new Color(255, 0, 0, 150), new Color(0, 255, 0, 150), new Color(0, 0, 255, 150),
-				new Color(255, 255, 0, 150), new Color(0, 255, 255, 150) };
-
-		int colorIndex = 0;
-
-		double letterX = Main.map.mapView.getBounds().getMinX() + 20;
-		double letterY = Main.map.mapView.getBounds().getMinY() + 100;
-
-		for (Character c : fixVariants.keySet()) {
-			if (fixVariants.get(c) != null) {
-				// drawFixVariant(fixVariants.get(c), colors[colorIndex % 5]);
-				drawFixVariantLetter(c.toString(), colors[colorIndex % 5], letterX, letterY);
-				colorIndex++;
-				letterY = letterY + 60;
-			}
-		}
-
-		// display the "Esc" label:
-		if (!fixVariants.isEmpty()) {
-			drawFixVariantLetter("Esc", Color.WHITE, letterX, letterY);
-		}
-	}
-
-	/**
-	 * 
-	 * @param fixVariant
-	 * @param color
-	 */
-	@SuppressWarnings("unused")
-	private void drawFixVariant(List<PTWay> fixVariant, Color color) {
-		for (PTWay ptway : fixVariant) {
-			for (Way way : ptway.getWays()) {
-				for (Pair<Node, Node> nodePair : way.getNodePairs(false)) {
-					drawSegment(nodePair.a, nodePair.b, color, 0);
-				}
-			}
-		}
-	}
-
-	/**
-	 * 
-	 * @param wayColoring
-	 */
-	protected void drawFixVariantsWithParallelLines(Map<Way, List<Character>> wayColoring, int numberOfFixVariants) {
-
-		HashMap<Character, Color> colors = new HashMap<>();
-		colors.put('A', new Color(255, 0, 0, 200));
-		colors.put('B', new Color(0, 255, 0, 200));
-		colors.put('C', new Color(0, 0, 255, 200));
-		colors.put('D', new Color(255, 255, 0, 200));
-		colors.put('E', new Color(0, 255, 255, 200));
-
-		for (Way way : wayColoring.keySet()) {
-			List<Character> letterList = wayColoring.get(way);
-			List<Color> wayColors = new ArrayList<>();
-			for (Character letter : letterList) {
-				wayColors.add(colors.get(letter));
-			}
-			for (Pair<Node, Node> nodePair : way.getNodePairs(false)) {
-				drawSegmentWithParallelLines(nodePair.a, nodePair.b, wayColors);
-			}
-		}
-	}
-
-	/**
-	 * 
-	 * @param n1
-	 * @param n2
-	 * @param color
-	 */
-	protected void drawSegmentWithParallelLines(Node n1, Node n2, List<Color> colors) {
-		if (!n1.isDrawable() || !n2.isDrawable() || !isSegmentVisible(n1, n2)) {
-			return;
-		}
-
-		Point p1 = mv.getPoint(n1);
-		Point p2 = mv.getPoint(n2);
-		double t = Math.atan2((double) p2.x - p1.x, (double) p2.y - p1.y);
-		double cosT = 9 * Math.cos(t);
-		double sinT = 9 * Math.sin(t);
-		double heightCosT = 9 * Math.cos(t);
-		double heightSinT = 9 * Math.sin(t);
-
-		double prevPointX = p1.x;
-		double prevPointY = p1.y;
-		double nextPointX = p1.x + heightSinT;
-		double nextPointY = p1.y + heightCosT;
-
-		Color currentColor = colors.get(0);
-		int i = 0;
-		g.setColor(currentColor);
-		g.fillOval((int) (p1.x - 9), (int) (p1.y - 9), 18, 18);
-
-		if (colors.size() == 1) {
-			int[] xPoints = { (int) (p1.x + cosT), (int) (p2.x + cosT), (int) (p2.x - cosT), (int) (p1.x - cosT) };
-			int[] yPoints = { (int) (p1.y - sinT), (int) (p2.y - sinT), (int) (p2.y + sinT), (int) (p1.y + sinT) };
-			g.setColor(currentColor);
-			g.fillPolygon(xPoints, yPoints, 4);
-		} else {
-			boolean iterate = true;
-			while (iterate) {
-				currentColor = colors.get(i % colors.size());
-
-				int[] xPoints = { (int) (prevPointX + cosT), (int) (nextPointX + cosT), (int) (nextPointX - cosT),
-						(int) (prevPointX - cosT) };
-				int[] yPoints = { (int) (prevPointY - sinT), (int) (nextPointY - sinT), (int) (nextPointY + sinT),
-						(int) (prevPointY + sinT) };
-				g.setColor(currentColor);
-				g.fillPolygon(xPoints, yPoints, 4);
-
-				prevPointX = prevPointX + heightSinT;
-				prevPointY = prevPointY + heightCosT;
-				nextPointX = nextPointX + heightSinT;
-				nextPointY = nextPointY + heightCosT;
-				i++;
-				if ((p1.x < p2.x && nextPointX >= p2.x) || (p1.x >= p2.x && nextPointX <= p2.x)) {
-					iterate = false;
-				}
-			}
-
-			int[] lastXPoints = { (int) (prevPointX + cosT), (int) (p2.x + cosT), (int) (p2.x - cosT),
-					(int) (prevPointX - cosT) };
-			int[] lastYPoints = { (int) (prevPointY - sinT), (int) (p2.y - sinT), (int) (p2.y + sinT),
-					(int) (prevPointY + sinT) };
-			g.setColor(currentColor);
-			g.fillPolygon(lastXPoints, lastYPoints, 4);
-		}
-
-		g.setColor(currentColor);
-		g.fillOval((int) (p2.x - 9), (int) (p2.y - 9), 18, 18);
-	}
-
-	/**
-	 * Visuallizes the letters for each fix variant
-	 * @param letter
-	 * @param color
-	 * @param letterX
-	 * @param letterY
-	 */
-	private void drawFixVariantLetter(String letter, Color color, double letterX, double letterY) {
-		g.setColor(color);
-		Font stringFont = new Font("SansSerif", Font.PLAIN, 50);
-		g.setFont(stringFont);
-		try {
-			g.drawString(letter, (int) letterX, (int) letterY);
-			g.drawString(letter, (int) letterX, (int) letterY);
-		} catch (NullPointerException ex) {
-			// do nothing
-		}
-
-	}
+    /** The graphics */
+    private final Graphics g;
+    /** The MapView */
+    private final MapView mv;
+
+    /**
+     * Constructor
+     *
+     * @param g graphics
+     * @param mv map view
+     */
+    public PTAssistantPaintVisitor(Graphics g, MapView mv) {
+        super(g, mv);
+        this.g = g;
+        this.mv = mv;
+    }
+
+    @Override
+    public void visit(Relation r) {
+
+        // first, draw primitives:
+        for (RelationMember rm : r.getMembers()) {
+
+            if (RouteUtils.isPTStop(rm)) {
+
+                drawStop(rm.getMember());
+
+            } else if (RouteUtils.isPTWay(rm)) {
+                if (rm.isWay()) {
+                    visit(rm.getWay());
+                } else if (rm.isRelation()) {
+                    visit(rm.getRelation());
+                } //else {
+                    // if the relation has members that do not fit with the
+                    // PT_Assistant data model, do nothing
+                //}
+            } //else {
+                // if the relation has members that do not fit with the
+                // PT_Assistant data model, do nothing
+            //}
+        }
+
+        // in the end, draw labels:
+        HashMap<Long, String> stopOrderMap = new HashMap<>();
+        int stopCount = 1;
+
+        for (RelationMember rm : r.getMembers()) {
+            if (RouteUtils.isPTStop(rm) || (rm.getMember().isIncomplete() && (rm.isNode() || rm.hasRole("stop")
+                    || rm.hasRole("stop_entry_only") || rm.hasRole("stop_exit_only") || rm.hasRole("platform")
+                    || rm.hasRole("platform_entry_only") || rm.hasRole("platform_exit_only")))) {
+
+                String label = "";
+
+                if (stopOrderMap.containsKey(rm.getUniqueId())) {
+                    label = stopOrderMap.get(rm.getUniqueId());
+                    label = label + ";" + stopCount;
+                } else {
+                    if (r.hasKey("ref")) {
+                        label = label + r.get("ref");
+                    } else if (r.hasKey("name")) {
+                        label = label + r.get("name");
+                    } else {
+                        label = "NA";
+                    }
+                    label = label + " - " + stopCount;
+                }
+
+                stopOrderMap.put(rm.getUniqueId(), label);
+                try {
+                    drawStopLabel(rm.getMember(), label);
+                } catch (NullPointerException ex) {
+                    // do nothing
+                    Main.trace(ex);
+                }
+                stopCount++;
+            }
+        }
+
+    }
+
+    @Override
+    public void visit(Way w) {
+
+        if (w == null) {
+            return;
+        }
+
+        /*-
+         * oneway values:
+         * 0 two-way street
+         * 1 oneway street in the way's direction
+         * 2 oneway street in ways's direction but public transport allowed
+         * -1 oneway street in reverse direction
+         * -2 oneway street in reverse direction but public transport allowed
+         */
+        int oneway = 0;
+
+        if (w.hasTag("junction", "roundabout") || w.hasTag("highway", "motorway")) {
+            oneway = 1;
+        } else if (w.hasTag("oneway", "1") || w.hasTag("oneway", "yes") || w.hasTag("oneway", "true")) {
+            if (w.hasTag("busway", "lane") || w.hasTag("busway:left", "lane") || w.hasTag("busway:right", "lane")
+                    || w.hasTag("oneway:bus", "no") || w.hasTag("busway", "opposite_lane")
+                    || w.hasTag("oneway:psv", "no") || w.hasTag("trolley_wire", "backward")) {
+                oneway = 2;
+            } else {
+                oneway = 1;
+            }
+        } else if (w.hasTag("oneway", "-1") || w.hasTag("oneway", "reverse")) {
+            if (w.hasTag("busway", "lane") || w.hasTag("busway:left", "lane") || w.hasTag("busway:right", "lane")
+                    || w.hasTag("oneway:bus", "no") || w.hasTag("busway", "opposite_lane")
+                    || w.hasTag("oneway:psv", "no") || w.hasTag("trolley_wire", "backward")) {
+                oneway = -2;
+            } else {
+                oneway = -1;
+            }
+        }
+
+        visit(w.getNodes(), oneway);
+
+    }
+
+    /**
+     * Variation of the visit method that allows a special visualization of
+     * oneway roads
+     *
+     * @param nodes nodes
+     * @param oneway oneway
+     */
+    public void visit(List<Node> nodes, int oneway) {
+        Node lastN = null;
+        for (Node n : nodes) {
+            if (lastN == null) {
+                lastN = n;
+                continue;
+            }
+            this.drawSegment(lastN, n, new Color(128, 0, 128, 100), oneway);
+            lastN = n;
+        }
+    }
+
+    /**
+     * Draw a small rectangle. White if selected (as always) or red otherwise.
+     *
+     * @param n
+     *            The node to draw.
+     */
+    @Override
+    public void visit(Node n) {
+        if (n.isDrawable() && isNodeVisible(n)) {
+            drawNode(n, Color.BLUE);
+        }
+    }
+
+    /**
+     * Draws a line around the segment
+     *
+     * @param n1
+     *            The first node of segment
+     * @param n2
+     *            The second node of segment
+     * @param color
+     *            The color
+     */
+    protected void drawSegment(Node n1, Node n2, Color color, int oneway) {
+        if (n1.isDrawable() && n2.isDrawable() && isSegmentVisible(n1, n2)) {
+            try {
+                drawSegment(mv.getPoint(n1), mv.getPoint(n2), color, oneway);
+            } catch (NullPointerException ex) {
+                // do nothing
+                Main.trace(ex);
+            }
+
+        }
+    }
+
+    /**
+     * Draws a line around the segment
+     *
+     * @param p1
+     *            The first point of segment
+     * @param p2
+     *            The second point of segment
+     * @param color
+     *            The color
+     */
+    protected void drawSegment(Point p1, Point p2, Color color, int oneway) {
+
+        double t = Math.atan2((double) p2.x - p1.x, (double) p2.y - p1.y);
+        double cosT = 9 * Math.cos(t);
+        double sinT = 9 * Math.sin(t);
+
+        int[] xPoints = {(int) (p1.x + cosT), (int) (p2.x + cosT), (int) (p2.x - cosT), (int) (p1.x - cosT)};
+        int[] yPoints = {(int) (p1.y - sinT), (int) (p2.y - sinT), (int) (p2.y + sinT), (int) (p1.y + sinT)};
+        g.setColor(color);
+        g.fillPolygon(xPoints, yPoints, 4);
+        g.fillOval(p1.x - 9, p1.y - 9, 18, 18);
+        g.fillOval(p2.x - 9, p2.y - 9, 18, 18);
+
+        if (oneway != 0) {
+            double middleX = (p1.x + p2.x) / 2.0;
+            double middleY = (p1.y + p2.y) / 2.0;
+            double cosTriangle = 6 * Math.cos(t);
+            double sinTriangle = 6 * Math.sin(t);
+            g.setColor(Color.WHITE);
+
+            if (oneway > 0) {
+                int[] xFillTriangle = {(int) (middleX + cosTriangle), (int) (middleX - cosTriangle),
+                        (int) (middleX + 2 * sinTriangle)};
+                int[] yFillTriangle = {(int) (middleY - sinTriangle), (int) (middleY + sinTriangle),
+                        (int) (middleY + 2 * cosTriangle)};
+                g.fillPolygon(xFillTriangle, yFillTriangle, 3);
+
+                if (oneway == 2) {
+                    int[] xDrawTriangle = {(int) (middleX + cosTriangle), (int) (middleX - cosTriangle),
+                            (int) (middleX - 2 * sinTriangle)};
+                    int[] yDrawTriangle = {(int) (middleY - sinTriangle), (int) (middleY + sinTriangle),
+                            (int) (middleY - 2 * cosTriangle)};
+                    g.drawPolygon(xDrawTriangle, yDrawTriangle, 3);
+                }
+            }
+
+            if (oneway < 0) {
+                int[] xFillTriangle = {(int) (middleX + cosTriangle), (int) (middleX - cosTriangle),
+                        (int) (middleX - 2 * sinTriangle)};
+                int[] yFillTriangle = {(int) (middleY - sinTriangle), (int) (middleY + sinTriangle),
+                        (int) (middleY - 2 * cosTriangle)};
+                g.fillPolygon(xFillTriangle, yFillTriangle, 3);
+
+                if (oneway == -2) {
+                    int[] xDrawTriangle = {(int) (middleX + cosTriangle), (int) (middleX - cosTriangle),
+                            (int) (middleX + 2 * sinTriangle)};
+                    int[] yDrawTriangle = {(int) (middleY - sinTriangle), (int) (middleY + sinTriangle),
+                            (int) (middleY + 2 * cosTriangle)};
+                    g.drawPolygon(xDrawTriangle, yDrawTriangle, 3);
+                }
+            }
+
+        }
+
+    }
+
+    /**
+     * Draws a circle around the node
+     *
+     * @param n
+     *            The node
+     * @param color
+     *            The circle color
+     */
+    @Override
+    protected void drawNode(Node n, Color color) {
+
+        Point p = mv.getPoint(n);
+
+        g.setColor(color);
+        g.drawOval(p.x - 5, p.y - 5, 10, 10);
+
+    }
+
+    /**
+     * Draws s stop_position as a blue circle; draws a platform as a blue square
+     *
+     * @param primitive primitive
+     */
+    protected void drawStop(OsmPrimitive primitive) {
+
+        // find the point to which the stop visualization will be linked:
+        Node n = new Node(primitive.getBBox().getCenter());
+
+        Point p = mv.getPoint(n);
+
+        g.setColor(Color.BLUE);
+
+        if (primitive.hasTag("public_transport", "stop_position") && p != null) {
+            g.fillOval(p.x - 8, p.y - 8, 16, 16);
+        } else {
+            g.fillRect(p.x - 8, p.y - 8, 16, 16);
+        }
+
+    }
+
+    /**
+     * Draws the labels for the stops, which include the ordered position of the
+     * stop in the route and the ref numbers of other routes that use this stop
+     *
+     * @param primitive primitive
+     * @param label label
+     */
+    protected void drawStopLabel(OsmPrimitive primitive, String label) {
+
+        // find the point to which the stop visualization will be linked:
+        Node n = new Node(primitive.getBBox().getCenter());
+
+        Point p = mv.getPoint(n);
+
+        if (label != null && !label.equals("")) {
+            g.setColor(Color.WHITE);
+            Font stringFont = new Font("SansSerif", Font.PLAIN, 24);
+            g.setFont(stringFont);
+            g.drawString(label, p.x + 20, p.y - 20);
+        }
+
+        // draw the ref values of all parent routes:
+        List<String> parentsLabelList = new ArrayList<>();
+        for (OsmPrimitive parent : primitive.getReferrers()) {
+            if (parent.getType().equals(OsmPrimitiveType.RELATION)) {
+                Relation relation = (Relation) parent;
+                if (RouteUtils.isTwoDirectionRoute(relation) && relation.get("ref") != null
+                        && !relation.get("ref").equals("")) {
+
+                    boolean stringFound = false;
+                    for (String s : parentsLabelList) {
+                        if (s.equals(relation.get("ref"))) {
+                            stringFound = true;
+                        }
+                    }
+                    if (!stringFound) {
+                        parentsLabelList.add(relation.get("ref"));
+                    }
+
+                }
+            }
+        }
+
+        Collections.sort(parentsLabelList, new RefTagComparator());
+
+        String parentsLabel = "";
+        for (String s : parentsLabelList) {
+            parentsLabel = parentsLabel + s + ";";
+        }
+
+        if (!parentsLabel.equals("")) {
+            // remove the last semicolon:
+            parentsLabel = parentsLabel.substring(0, parentsLabel.length() - 1);
+
+            g.setColor(new Color(255, 20, 147));
+            Font parentLabelFont = new Font("SansSerif", Font.ITALIC, 20);
+            g.setFont(parentLabelFont);
+            g.drawString(parentsLabel, p.x + 20, p.y + 20);
+        }
+
+    }
+
+    /**
+     * Compares route ref numbers
+     * @author darya
+     *
+     */
+    private class RefTagComparator implements Comparator<String> {
+
+        @Override
+        public int compare(String s1, String s2) {
+
+            if (s1 == null || s1.equals("") || s2 == null || s2.equals("")) {
+                // if at least one of the strings is null or empty, there is no
+                // point in comparing:
+                return 0;
+            }
+
+            String[] splitString1 = s1.split("\\D");
+            String[] splitString2 = s2.split("\\D");
+
+            if (splitString1.length == 0 && splitString2.length != 0) {
+                // if the first ref does not start a digit and the second ref
+                // starts with a digit:
+                return 1;
+            }
+
+            if (splitString1.length != 0 && splitString2.length == 0) {
+                // if the first ref starts a digit and the second ref does not
+                // start with a digit:
+                return -1;
+            }
+
+            if (splitString1.length == 0 && splitString2.length == 0) {
+                // if both ref values do not start with a digit:
+                return s1.compareTo(s2);
+            }
+
+            String firstNumberString1 = splitString1[0];
+            String firstNumberString2 = splitString2[0];
+
+            try {
+                int firstNumber1 = Integer.valueOf(firstNumberString1);
+                int firstNumber2 = Integer.valueOf(firstNumberString2);
+                if (firstNumber1 > firstNumber2) {
+                    return 1;
+                } else if (firstNumber1 < firstNumber2) {
+                    return -1;
+                } else {
+                    // if the first number is the same:
+
+                    return s1.compareTo(s2);
+
+                }
+            } catch (NumberFormatException ex) {
+                return s1.compareTo(s2);
+            }
+
+        }
+
+    }
+
+    /**
+     * Visualizes the fix variants, assigns colors to them based on their order
+     * @param fixVariants fix variants
+     */
+    protected void visitFixVariants(HashMap<Character, List<PTWay>> fixVariants,
+            HashMap<Way, List<Character>> wayColoring) {
+
+        drawFixVariantsWithParallelLines(wayColoring, fixVariants.size());
+
+        Color[] colors = {
+                new Color(255, 0, 0, 150),
+                new Color(0, 255, 0, 150),
+                new Color(0, 0, 255, 150),
+                new Color(255, 255, 0, 150),
+                new Color(0, 255, 255, 150)};
+
+        int colorIndex = 0;
+
+        double letterX = Main.map.mapView.getBounds().getMinX() + 20;
+        double letterY = Main.map.mapView.getBounds().getMinY() + 100;
+
+        for (Character c : fixVariants.keySet()) {
+            if (fixVariants.get(c) != null) {
+                // drawFixVariant(fixVariants.get(c), colors[colorIndex % 5]);
+                drawFixVariantLetter(c.toString(), colors[colorIndex % 5], letterX, letterY);
+                colorIndex++;
+                letterY = letterY + 60;
+            }
+        }
+
+        // display the "Esc" label:
+        if (!fixVariants.isEmpty()) {
+            drawFixVariantLetter("Esc", Color.WHITE, letterX, letterY);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private void drawFixVariant(List<PTWay> fixVariant, Color color) {
+        for (PTWay ptway : fixVariant) {
+            for (Way way : ptway.getWays()) {
+                for (Pair<Node, Node> nodePair : way.getNodePairs(false)) {
+                    drawSegment(nodePair.a, nodePair.b, color, 0);
+                }
+            }
+        }
+    }
+
+    protected void drawFixVariantsWithParallelLines(Map<Way, List<Character>> wayColoring, int numberOfFixVariants) {
+
+        HashMap<Character, Color> colors = new HashMap<>();
+        colors.put('A', new Color(255, 0, 0, 200));
+        colors.put('B', new Color(0, 255, 0, 200));
+        colors.put('C', new Color(0, 0, 255, 200));
+        colors.put('D', new Color(255, 255, 0, 200));
+        colors.put('E', new Color(0, 255, 255, 200));
+
+        for (Way way : wayColoring.keySet()) {
+            List<Character> letterList = wayColoring.get(way);
+            List<Color> wayColors = new ArrayList<>();
+            for (Character letter : letterList) {
+                wayColors.add(colors.get(letter));
+            }
+            for (Pair<Node, Node> nodePair : way.getNodePairs(false)) {
+                drawSegmentWithParallelLines(nodePair.a, nodePair.b, wayColors);
+            }
+        }
+    }
+
+    protected void drawSegmentWithParallelLines(Node n1, Node n2, List<Color> colors) {
+        if (!n1.isDrawable() || !n2.isDrawable() || !isSegmentVisible(n1, n2)) {
+            return;
+        }
+
+        Point p1 = mv.getPoint(n1);
+        Point p2 = mv.getPoint(n2);
+        double t = Math.atan2((double) p2.x - p1.x, (double) p2.y - p1.y);
+        double cosT = 9 * Math.cos(t);
+        double sinT = 9 * Math.sin(t);
+        double heightCosT = 9 * Math.cos(t);
+        double heightSinT = 9 * Math.sin(t);
+
+        double prevPointX = p1.x;
+        double prevPointY = p1.y;
+        double nextPointX = p1.x + heightSinT;
+        double nextPointY = p1.y + heightCosT;
+
+        Color currentColor = colors.get(0);
+        int i = 0;
+        g.setColor(currentColor);
+        g.fillOval(p1.x - 9, p1.y - 9, 18, 18);
+
+        if (colors.size() == 1) {
+            int[] xPoints = {(int) (p1.x + cosT), (int) (p2.x + cosT), (int) (p2.x - cosT), (int) (p1.x - cosT)};
+            int[] yPoints = {(int) (p1.y - sinT), (int) (p2.y - sinT), (int) (p2.y + sinT), (int) (p1.y + sinT)};
+            g.setColor(currentColor);
+            g.fillPolygon(xPoints, yPoints, 4);
+        } else {
+            boolean iterate = true;
+            while (iterate) {
+                currentColor = colors.get(i % colors.size());
+
+                int[] xPoints = {(int) (prevPointX + cosT), (int) (nextPointX + cosT), (int) (nextPointX - cosT),
+                        (int) (prevPointX - cosT)};
+                int[] yPoints = {(int) (prevPointY - sinT), (int) (nextPointY - sinT), (int) (nextPointY + sinT),
+                        (int) (prevPointY + sinT)};
+                g.setColor(currentColor);
+                g.fillPolygon(xPoints, yPoints, 4);
+
+                prevPointX = prevPointX + heightSinT;
+                prevPointY = prevPointY + heightCosT;
+                nextPointX = nextPointX + heightSinT;
+                nextPointY = nextPointY + heightCosT;
+                i++;
+                if ((p1.x < p2.x && nextPointX >= p2.x) || (p1.x >= p2.x && nextPointX <= p2.x)) {
+                    iterate = false;
+                }
+            }
+
+            int[] lastXPoints = {(int) (prevPointX + cosT), (int) (p2.x + cosT), (int) (p2.x - cosT),
+                    (int) (prevPointX - cosT)};
+            int[] lastYPoints = {(int) (prevPointY - sinT), (int) (p2.y - sinT), (int) (p2.y + sinT),
+                    (int) (prevPointY + sinT)};
+            g.setColor(currentColor);
+            g.fillPolygon(lastXPoints, lastYPoints, 4);
+        }
+
+        g.setColor(currentColor);
+        g.fillOval(p2.x - 9, p2.y - 9, 18, 18);
+    }
+
+    /**
+     * Visuallizes the letters for each fix variant
+     * @param letter letter
+     * @param color color
+     * @param letterX letter X
+     * @param letterY letter Y
+     */
+    private void drawFixVariantLetter(String letter, Color color, double letterX, double letterY) {
+        g.setColor(color);
+        Font stringFont = new Font("SansSerif", Font.PLAIN, 50);
+        g.setFont(stringFont);
+        try {
+            g.drawString(letter, (int) letterX, (int) letterY);
+            g.drawString(letter, (int) letterX, (int) letterY);
+        } catch (NullPointerException ex) {
+            // do nothing
+            Main.trace(ex);
+        }
+
+    }
 
 }
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/PTAssistantPreferenceSetting.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/PTAssistantPreferenceSetting.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/PTAssistantPreferenceSetting.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.gui;
 
@@ -21,51 +22,51 @@
 public class PTAssistantPreferenceSetting implements SubPreferenceSetting {
 
-	private final JCheckBox downloadIncompleteMembers = new JCheckBox(I18n.tr("Download incomplete route relation members"));
-	private final JCheckBox stopArea = new JCheckBox(I18n.tr("Include stop_area tests"));
-	
-	/**
-	 * Setting up the pt_assistant preference tab
-	 */
-	@Override
-	public void addGui(PreferenceTabbedPane gui) {
+    private final JCheckBox downloadIncompleteMembers = new JCheckBox(I18n.tr("Download incomplete route relation members"));
+    private final JCheckBox stopArea = new JCheckBox(I18n.tr("Include stop_area tests"));
 
-		JPanel mainPanel = new JPanel();
-		mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
-		mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 20, 5, 5));
-		
-		mainPanel.add(downloadIncompleteMembers);
-		mainPanel.add(stopArea);
-		
-		downloadIncompleteMembers.setSelected(Main.pref.getBoolean("pt_assistant.download-incomplete", false));
-		stopArea.setSelected(Main.pref.getBoolean("pt_assistant.stop-area-tests", true));
+    /**
+     * Setting up the pt_assistant preference tab
+     */
+    @Override
+    public void addGui(PreferenceTabbedPane gui) {
 
-		synchronized (gui.getDisplayPreference().getTabPane()) {
-			gui.getValidatorPreference().addSubTab(this, "PT_Assistant", new JScrollPane(mainPanel));
-			gui.getValidatorPreference().getTabPane().setIconAt(gui.getValidatorPreference().getTabPane().getTabCount() - 1,
-					new ImageProvider("presets/transport", "bus.svg").get());
+        JPanel mainPanel = new JPanel();
+        mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
+        mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 20, 5, 5));
 
-		}
+        mainPanel.add(downloadIncompleteMembers);
+        mainPanel.add(stopArea);
 
-	}
+        downloadIncompleteMembers.setSelected(Main.pref.getBoolean("pt_assistant.download-incomplete", false));
+        stopArea.setSelected(Main.pref.getBoolean("pt_assistant.stop-area-tests", true));
 
-	@Override
-	public boolean isExpert() {
-		return false;
-	}
+        synchronized (gui.getDisplayPreference().getTabPane()) {
+            gui.getValidatorPreference().addSubTab(this, "PT_Assistant", new JScrollPane(mainPanel));
+            gui.getValidatorPreference().getTabPane().setIconAt(gui.getValidatorPreference().getTabPane().getTabCount() - 1,
+                    new ImageProvider("presets/transport", "bus.svg").get());
 
-	/**
-	 * Action to be performed when the OK button is pressed
-	 */
-	@Override
-	public boolean ok() {
-	    Main.pref.put("pt_assistant.download-incomplete", this.downloadIncompleteMembers.isSelected());
-	    Main.pref.put("pt_assistant.stop-area-tests", this.stopArea.isSelected());
-		return false;
-	}
+        }
 
-	@Override
-	public TabPreferenceSetting getTabPreferenceSetting(PreferenceTabbedPane gui) {
-		return gui.getDisplayPreference();
-	}
+    }
+
+    @Override
+    public boolean isExpert() {
+        return false;
+    }
+
+    /**
+     * Action to be performed when the OK button is pressed
+     */
+    @Override
+    public boolean ok() {
+        Main.pref.put("pt_assistant.download-incomplete", this.downloadIncompleteMembers.isSelected());
+        Main.pref.put("pt_assistant.stop-area-tests", this.stopArea.isSelected());
+        return false;
+    }
+
+    @Override
+    public TabPreferenceSetting getTabPreferenceSetting(PreferenceTabbedPane gui) {
+        return gui.getDisplayPreference();
+    }
 
 }
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/ProceedDialog.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/ProceedDialog.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/ProceedDialog.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.gui;
 
@@ -19,5 +20,5 @@
  * (i.e. if the errors found in the first stage of testing should be fixed
  * before continuing with the testing).
- * 
+ *
  * @author darya
  *
@@ -25,143 +26,143 @@
 public class ProceedDialog extends JPanel {
 
-	private static final long serialVersionUID = 2986537034076698693L;
+    private static final long serialVersionUID = 2986537034076698693L;
 
-	public enum ASK_TO_PROCEED {
-		DO_ASK, DONT_ASK_AND_FIX_AUTOMATICALLY, DONT_ASK_AND_FIX_MANUALLY, DONT_ASK_AND_DONT_FIX
-	};
+    public enum ASK_TO_PROCEED {
+        DO_ASK, DONT_ASK_AND_FIX_AUTOMATICALLY, DONT_ASK_AND_FIX_MANUALLY, DONT_ASK_AND_DONT_FIX
+    }
 
-	// by default, the user should be asked
-	public static ASK_TO_PROCEED askToProceed;
+    // by default, the user should be asked
+    public static ASK_TO_PROCEED askToProceed;
 
-	private JRadioButton radioButtonFixAutomatically;
-	private JRadioButton radioButtonFixManually;
-	private JRadioButton radioButtonDontFix;
-	private JCheckBox checkbox;
-	private String[] options;
-	private JPanel panel;
-	private int selectedOption;
+    private JRadioButton radioButtonFixAutomatically;
+    private JRadioButton radioButtonFixManually;
+    private JRadioButton radioButtonDontFix;
+    private JCheckBox checkbox;
+    private String[] options;
+    private JPanel panel;
+    private int selectedOption;
 
-	public ProceedDialog(long id, int numberOfDirectionErrors, int numberOfRoadTypeErrors) {
+    public ProceedDialog(long id, int numberOfDirectionErrors, int numberOfRoadTypeErrors) {
 
-		panel = new JPanel();
-		panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
+        panel = new JPanel();
+        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
 
-		JLabel label1 = new JLabel(tr("PT_Assistant plugin found that this relation (id={0}) has errors:", id));
-		panel.add(label1);
-		label1.setAlignmentX(Component.LEFT_ALIGNMENT);
+        JLabel label1 = new JLabel(tr("PT_Assistant plugin found that this relation (id={0}) has errors:", id));
+        panel.add(label1);
+        label1.setAlignmentX(Component.LEFT_ALIGNMENT);
 
-		if (true) {
-			JLabel label2 = new JLabel("     " + trn("{0} direction error", "{0} direction errors",
-					numberOfDirectionErrors, numberOfDirectionErrors));
-			panel.add(label2);
-			label2.setAlignmentX(Component.LEFT_ALIGNMENT);
-		}
+        if (true) {
+            JLabel label2 = new JLabel("     " + trn("{0} direction error", "{0} direction errors",
+                    numberOfDirectionErrors, numberOfDirectionErrors));
+            panel.add(label2);
+            label2.setAlignmentX(Component.LEFT_ALIGNMENT);
+        }
 
-		if (numberOfRoadTypeErrors != 0) {
-			JLabel label3 = new JLabel("     " + trn("{0} road type error", "{0} road type errors",
-					numberOfRoadTypeErrors, numberOfRoadTypeErrors));
-			panel.add(label3);
-			label3.setAlignmentX(Component.LEFT_ALIGNMENT);
-		}
+        if (numberOfRoadTypeErrors != 0) {
+            JLabel label3 = new JLabel("     " + trn("{0} road type error", "{0} road type errors",
+                    numberOfRoadTypeErrors, numberOfRoadTypeErrors));
+            panel.add(label3);
+            label3.setAlignmentX(Component.LEFT_ALIGNMENT);
+        }
 
-		JLabel label4 = new JLabel(tr("How do you want to proceed?"));
-		panel.add(label4);
-		label4.setAlignmentX(Component.LEFT_ALIGNMENT);
+        JLabel label4 = new JLabel(tr("How do you want to proceed?"));
+        panel.add(label4);
+        label4.setAlignmentX(Component.LEFT_ALIGNMENT);
 
-		radioButtonFixAutomatically = new JRadioButton("Fix all errors automatically and proceed");
-		radioButtonFixManually = new JRadioButton("I will fix the errors manually and click the button to proceed");
-		radioButtonDontFix = new JRadioButton("Do not fix anything and proceed with further tests", true);
-		ButtonGroup fixOptionButtonGroup = new ButtonGroup();
-		fixOptionButtonGroup.add(radioButtonFixAutomatically);
-		fixOptionButtonGroup.add(radioButtonFixManually);
-		fixOptionButtonGroup.add(radioButtonDontFix);
-		panel.add(radioButtonFixAutomatically);
-		// panel.add(radioButtonFixManually);
-		panel.add(radioButtonDontFix);
-		radioButtonFixAutomatically.setAlignmentX(Component.LEFT_ALIGNMENT);
-		radioButtonFixManually.setAlignmentX(Component.LEFT_ALIGNMENT);
-		radioButtonDontFix.setAlignmentX(Component.LEFT_ALIGNMENT);
+        radioButtonFixAutomatically = new JRadioButton("Fix all errors automatically and proceed");
+        radioButtonFixManually = new JRadioButton("I will fix the errors manually and click the button to proceed");
+        radioButtonDontFix = new JRadioButton("Do not fix anything and proceed with further tests", true);
+        ButtonGroup fixOptionButtonGroup = new ButtonGroup();
+        fixOptionButtonGroup.add(radioButtonFixAutomatically);
+        fixOptionButtonGroup.add(radioButtonFixManually);
+        fixOptionButtonGroup.add(radioButtonDontFix);
+        panel.add(radioButtonFixAutomatically);
+        // panel.add(radioButtonFixManually);
+        panel.add(radioButtonDontFix);
+        radioButtonFixAutomatically.setAlignmentX(Component.LEFT_ALIGNMENT);
+        radioButtonFixManually.setAlignmentX(Component.LEFT_ALIGNMENT);
+        radioButtonDontFix.setAlignmentX(Component.LEFT_ALIGNMENT);
 
-		checkbox = new JCheckBox(tr("Remember my choice and do not ask me again in this session"));
-		panel.add(checkbox);
-		checkbox.setAlignmentX(Component.LEFT_ALIGNMENT);
+        checkbox = new JCheckBox(tr("Remember my choice and do not ask me again in this session"));
+        panel.add(checkbox);
+        checkbox.setAlignmentX(Component.LEFT_ALIGNMENT);
 
-		options = new String[2];
-		options[0] = "OK";
-		options[1] = "Cancel & stop testing";
+        options = new String[2];
+        options[0] = "OK";
+        options[1] = "Cancel & stop testing";
 
-		selectedOption = Integer.MIN_VALUE;
+        selectedOption = Integer.MIN_VALUE;
 
-	}
+    }
 
-	/**
-	 * Finds out whether the user wants to download incomplete members. In the
-	 * default case, creates a JOptionPane to ask.
-	 * 
-	 * @return 0 to fix automatically, 1 to fix manually, 2 to proceed without
-	 *         fixing, -1 to stop testing or if dialog is closed without answer
-	 * 
-	 */
-	public int getUserSelection() {
+    /**
+     * Finds out whether the user wants to download incomplete members. In the
+     * default case, creates a JOptionPane to ask.
+     *
+     * @return 0 to fix automatically, 1 to fix manually, 2 to proceed without
+     *         fixing, -1 to stop testing or if dialog is closed without answer
+     *
+     */
+    public int getUserSelection() {
 
-		if (askToProceed == ASK_TO_PROCEED.DONT_ASK_AND_FIX_AUTOMATICALLY) {
-			return 0;
-		}
-		if (askToProceed == ASK_TO_PROCEED.DONT_ASK_AND_FIX_MANUALLY) {
-			return 1;
-		}
-		if (askToProceed == ASK_TO_PROCEED.DONT_ASK_AND_DONT_FIX) {
-			return 2;
-		}
+        if (askToProceed == ASK_TO_PROCEED.DONT_ASK_AND_FIX_AUTOMATICALLY) {
+            return 0;
+        }
+        if (askToProceed == ASK_TO_PROCEED.DONT_ASK_AND_FIX_MANUALLY) {
+            return 1;
+        }
+        if (askToProceed == ASK_TO_PROCEED.DONT_ASK_AND_DONT_FIX) {
+            return 2;
+        }
 
-		// showDialog(); FIXME
-		selectedOption = JOptionPane.showOptionDialog(this, panel, tr("PT_Assistant Proceed Request"),
-				JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, 0);
+        // showDialog(); FIXME
+        selectedOption = JOptionPane.showOptionDialog(this, panel, tr("PT_Assistant Proceed Request"),
+                JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, 0);
 
-		if (selectedOption == 0) {
-			if (radioButtonFixAutomatically.isSelected()) {
-				if (checkbox.isSelected()) {
-					askToProceed = ASK_TO_PROCEED.DONT_ASK_AND_FIX_AUTOMATICALLY;
-				}
-				return 0;
-			}
-			if (radioButtonFixManually.isSelected()) {
-				if (checkbox.isSelected()) {
-					askToProceed = ASK_TO_PROCEED.DONT_ASK_AND_FIX_MANUALLY;
-				}
-				return 1;
-			}
-			if (radioButtonDontFix.isSelected()) {
-				if (checkbox.isSelected()) {
-					askToProceed = ASK_TO_PROCEED.DONT_ASK_AND_DONT_FIX;
-				}
-				return 2;
-			}
-		}
+        if (selectedOption == 0) {
+            if (radioButtonFixAutomatically.isSelected()) {
+                if (checkbox.isSelected()) {
+                    askToProceed = ASK_TO_PROCEED.DONT_ASK_AND_FIX_AUTOMATICALLY;
+                }
+                return 0;
+            }
+            if (radioButtonFixManually.isSelected()) {
+                if (checkbox.isSelected()) {
+                    askToProceed = ASK_TO_PROCEED.DONT_ASK_AND_FIX_MANUALLY;
+                }
+                return 1;
+            }
+            if (radioButtonDontFix.isSelected()) {
+                if (checkbox.isSelected()) {
+                    askToProceed = ASK_TO_PROCEED.DONT_ASK_AND_DONT_FIX;
+                }
+                return 2;
+            }
+        }
 
-		return -1;
-	}
+        return -1;
+    }
 
-	/**
-	 * 
-	 */
-	@SuppressWarnings("unused")
-	private void showDialog() {
+    /**
+     *
+     */
+    @SuppressWarnings("unused")
+    private void showDialog() {
 
-		if (!SwingUtilities.isEventDispatchThread()) {
-			selectedOption = JOptionPane.showOptionDialog(this, panel, tr("PT_Assistant Proceed Request"),
-					JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, 0);
-		} else {
+        if (!SwingUtilities.isEventDispatchThread()) {
+            selectedOption = JOptionPane.showOptionDialog(this, panel, tr("PT_Assistant Proceed Request"),
+                    JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, 0);
+        } else {
 
-			SwingUtilities.invokeLater(new Runnable() {
-				@Override
-				public void run() {
-					showDialog();
-				}
-			});
+            SwingUtilities.invokeLater(new Runnable() {
+                @Override
+                public void run() {
+                    showDialog();
+                }
+            });
 
-		}
+        }
 
-	}
+    }
 
 }
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 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/utils/RouteUtils.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.utils;
 
@@ -12,233 +13,233 @@
 /**
  * Utils class for routes
- * 
+ *
  * @author darya
  *
  */
-public class RouteUtils {
-
-	private RouteUtils() {
-		// private constructor for util classes
-	}
-
-	/**
-	 * Checks if the relation is a route of one of the following categories:
-	 * bus, trolleybus, share_taxi, tram, light_rail, subway, train.
-	 * 
-	 * @param r
-	 *            Relation to be checked
-	 * @return true if the route belongs to the categories that can be validated
-	 *         with the pt_assistant plugin, false otherwise.
-	 */
-	public static boolean isTwoDirectionRoute(Relation r) {
-
-		if (r == null) {
-			return false;
-		}
-
-		if (!r.hasKey("route") || !r.hasTag("public_transport:version", "2")) {
-			return false;
-		}
-		if (r.hasTag("route", "bus") || r.hasTag("route", "trolleybus") || r.hasTag("route", "share_taxi")
-				|| r.hasTag("route", "tram") || r.hasTag("route", "light_rail") || r.hasTag("route", "subway")
-				|| r.hasTag("route", "train")) {
-
-			if (!r.hasTag("bus", "on_demand")) {
-				return true;
-			}
-
-		}
-		return false;
-	}
-
-	/**
-	 * Checks if the relation member refers to a stop in a public transport
-	 * route. Some stops can be modeled with ways.
-	 * 
-	 * @param rm
-	 *            relation member to be checked
-	 * @return true if the relation member refers to a stop, false otherwise
-	 */
-	public static boolean isPTStop(RelationMember rm) {
-
-
-		if (rm.getType().equals(OsmPrimitiveType.NODE)) {
-				return true;
-		}
-
-		if (rm.getType().equals(OsmPrimitiveType.WAY)) {
-			if (rm.getWay().hasTag("public_transport", "platform") || rm.getWay().hasTag("highway", "platform")
-					|| rm.getWay().hasTag("railway", "platform")) {
-				return true;
-			}
-		}
-
-		return false;
-
-	}
-
-	/**
-	 * Checks if the relation member refers to a way in a public transport
-	 * route. Some OsmPrimitiveType.WAY have to be excluded because platforms
-	 * can be modeled with ways.
-	 * 
-	 * @param rm
-	 *            relation member to be checked
-	 * @return true if the relation member refers to a way in a public transport
-	 *         route, false otherwise.
-	 */
-	public static boolean isPTWay(RelationMember rm) {
-
-		if (rm.getType().equals(OsmPrimitiveType.NODE)) {
-			return false;
-		}
-
-		if (rm.getType().equals(OsmPrimitiveType.WAY)) {
-			if (rm.getWay().hasTag("public_transport", "platform") || rm.getWay().hasTag("highway", "platform")
-					|| rm.getWay().hasTag("railway", "platform")) {
-				return false;
-			}
-			return true;
-		}
-
-		Relation nestedRelation = rm.getRelation();
-
-		for (RelationMember nestedRelationMember : nestedRelation.getMembers()) {
-			if (!nestedRelationMember.getType().equals(OsmPrimitiveType.WAY)) {
-				return false;
-			}
-		}
-
-		return true;
-	}
-
-	/**
-	 * Checks if the given way has tags that make it oneway for public
-	 * transport. The test does not check whether the way violates those
-	 * restrictions.
-	 * 
-	 * @return 0 if the way is not oneway for public transport, 1 if the way is
-	 *         oneway for public transport, -1 if the way is reversely oneway
-	 *         for public transport
-	 */
-	public static int isOnewayForPublicTransport(Way way) {
-
-		if (OsmUtils.isTrue(way.get("oneway")) || OsmUtils.isReversed(way.get("oneway"))
-				|| way.hasTag("junction", "roundabout") || way.hasTag("highway", "motorway")) {
-
-			if (!way.hasTag("busway", "lane") && !way.hasTag("busway:left", "lane")
-					&& !way.hasTag("busway:right", "lane") && !way.hasTag("oneway:bus", "no")
-					&& !way.hasTag("busway", "opposite_lane") && !way.hasTag("oneway:psv", "no")
-					&& !way.hasTag("trolley_wire", "backward")) {
-
-				if (OsmUtils.isReversed(way.get("oneway"))) {
-					return -1;
-				}
-
-				return 1;
-
-			}
-
-		}
-
-		return 0;
-	}
-
-	/**
-	 * Checks if the ways have a common node
-	 * 
-	 * @param w1
-	 * @param w2
-	 * @return
-	 */
-	public static boolean waysTouch(Way w1, Way w2) {
-
-		if (w1 == null || w2 == null) {
-			return false;
-		}
-
-		Node w1FirstNode = w1.firstNode();
-		Node w1LastNode = w1.lastNode();
-		Node w2FirstNode = w2.firstNode();
-		Node w2LastNode = w2.lastNode();
-
-		if (w1FirstNode == w2FirstNode || w1FirstNode == w2LastNode || w1LastNode == w2FirstNode
-				|| w1LastNode == w2LastNode) {
-			return true;
-		}
-
-		return false;
-	}
-
-	/**
-	 * Checks if any way from the first collection touches any way from the
-	 * second collection
-	 * 
-	 * @param c1 first collection
-	 * @param c2 second collection
-	 * @return true if ways touch, false otherwise
-	 */
-	public static boolean waysTouch(Collection<Way> c1, Collection<Way> c2) {
-
-		if (c1 == null || c2 == null) {
-			return false;
-		}
-
-		for (Way w1 : c1) {
-			for (Way w2 : c2) {
-				if (waysTouch(w1, w2)) {
-					return true;
-				}
-			}
-		}
-
-		return false;
-	}
-
-	/**
-	 * Checks if the type of the way is suitable for buses to go on it. The
-	 * direction of the way (i.e. one-way roads) is irrelevant for this test.
-	 * 
-	 * @param way
-	 *            to be checked
-	 * @return true if the way is suitable for buses, false otherwise.
-	 */
-	public static boolean isWaySuitableForBuses(Way way) {
-		if (way.hasTag("highway", "motorway") || way.hasTag("highway", "trunk") || way.hasTag("highway", "primary")
-				|| way.hasTag("highway", "secondary") || way.hasTag("highway", "tertiary")
-				|| way.hasTag("highway", "unclassified") || way.hasTag("highway", "road")
-				|| way.hasTag("highway", "residential") || way.hasTag("highway", "service")
-				|| way.hasTag("highway", "motorway_link") || way.hasTag("highway", "trunk_link")
-				|| way.hasTag("highway", "primary_link") || way.hasTag("highway", "secondary_link")
-				|| way.hasTag("highway", "tertiary_link") || way.hasTag("highway", "living_street")
-				|| way.hasTag("highway", "bus_guideway") || way.hasTag("highway", "road")
-				|| way.hasTag("cycleway", "share_busway") || way.hasTag("cycleway", "shared_lane")) {
-			return true;
-		}
-
-		if (way.hasTag("highway", "pedestrian") && (way.hasTag("bus", "yes") || way.hasTag("psv", "yes")
-				|| way.hasTag("bus", "designated") || way.hasTag("psv", "designated"))) {
-			return true;
-		}
-
-		return false;
-	}
-
-	/**
-	 * Checks if this way is suitable for public transport (not only for buses)
-	 * @param way
-	 * @return
-	 */
-	public static boolean isWaySuitableForPublicTransport(Way way) {
-
-		if (isWaySuitableForBuses(way) || way.hasTag("railway", "tram") || way.hasTag("railway", "subway")
-				|| way.hasTag("railway", "subway") || way.hasTag("railway", "light_rail")
-				|| way.hasTag("railway", "rail")) {
-			return true;
-		}
-
-		return false;
-
-	}
+public final class RouteUtils {
+
+    private RouteUtils() {
+        // private constructor for util classes
+    }
+
+    /**
+     * Checks if the relation is a route of one of the following categories:
+     * bus, trolleybus, share_taxi, tram, light_rail, subway, train.
+     *
+     * @param r
+     *            Relation to be checked
+     * @return true if the route belongs to the categories that can be validated
+     *         with the pt_assistant plugin, false otherwise.
+     */
+    public static boolean isTwoDirectionRoute(Relation r) {
+
+        if (r == null) {
+            return false;
+        }
+
+        if (!r.hasKey("route") || !r.hasTag("public_transport:version", "2")) {
+            return false;
+        }
+        if (r.hasTag("route", "bus") || r.hasTag("route", "trolleybus") || r.hasTag("route", "share_taxi")
+                || r.hasTag("route", "tram") || r.hasTag("route", "light_rail") || r.hasTag("route", "subway")
+                || r.hasTag("route", "train")) {
+
+            if (!r.hasTag("bus", "on_demand")) {
+                return true;
+            }
+
+        }
+        return false;
+    }
+
+    /**
+     * Checks if the relation member refers to a stop in a public transport
+     * route. Some stops can be modeled with ways.
+     *
+     * @param rm
+     *            relation member to be checked
+     * @return true if the relation member refers to a stop, false otherwise
+     */
+    public static boolean isPTStop(RelationMember rm) {
+
+
+        if (rm.getType().equals(OsmPrimitiveType.NODE)) {
+                return true;
+        }
+
+        if (rm.getType().equals(OsmPrimitiveType.WAY)) {
+            if (rm.getWay().hasTag("public_transport", "platform") || rm.getWay().hasTag("highway", "platform")
+                    || rm.getWay().hasTag("railway", "platform")) {
+                return true;
+            }
+        }
+
+        return false;
+
+    }
+
+    /**
+     * Checks if the relation member refers to a way in a public transport
+     * route. Some OsmPrimitiveType.WAY have to be excluded because platforms
+     * can be modeled with ways.
+     *
+     * @param rm
+     *            relation member to be checked
+     * @return true if the relation member refers to a way in a public transport
+     *         route, false otherwise.
+     */
+    public static boolean isPTWay(RelationMember rm) {
+
+        if (rm.getType().equals(OsmPrimitiveType.NODE)) {
+            return false;
+        }
+
+        if (rm.getType().equals(OsmPrimitiveType.WAY)) {
+            if (rm.getWay().hasTag("public_transport", "platform") || rm.getWay().hasTag("highway", "platform")
+                    || rm.getWay().hasTag("railway", "platform")) {
+                return false;
+            }
+            return true;
+        }
+
+        Relation nestedRelation = rm.getRelation();
+
+        for (RelationMember nestedRelationMember : nestedRelation.getMembers()) {
+            if (!nestedRelationMember.getType().equals(OsmPrimitiveType.WAY)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Checks if the given way has tags that make it oneway for public
+     * transport. The test does not check whether the way violates those
+     * restrictions.
+     *
+     * @return 0 if the way is not oneway for public transport, 1 if the way is
+     *         oneway for public transport, -1 if the way is reversely oneway
+     *         for public transport
+     */
+    public static int isOnewayForPublicTransport(Way way) {
+
+        if (OsmUtils.isTrue(way.get("oneway")) || OsmUtils.isReversed(way.get("oneway"))
+                || way.hasTag("junction", "roundabout") || way.hasTag("highway", "motorway")) {
+
+            if (!way.hasTag("busway", "lane") && !way.hasTag("busway:left", "lane")
+                    && !way.hasTag("busway:right", "lane") && !way.hasTag("oneway:bus", "no")
+                    && !way.hasTag("busway", "opposite_lane") && !way.hasTag("oneway:psv", "no")
+                    && !way.hasTag("trolley_wire", "backward")) {
+
+                if (OsmUtils.isReversed(way.get("oneway"))) {
+                    return -1;
+                }
+
+                return 1;
+
+            }
+
+        }
+
+        return 0;
+    }
+
+    /**
+     * Checks if the ways have a common node
+     *
+     * @param w1 first way
+     * @param w2 second way
+     * @return {@code true} if the ways have a common node
+     */
+    public static boolean waysTouch(Way w1, Way w2) {
+
+        if (w1 == null || w2 == null) {
+            return false;
+        }
+
+        Node w1FirstNode = w1.firstNode();
+        Node w1LastNode = w1.lastNode();
+        Node w2FirstNode = w2.firstNode();
+        Node w2LastNode = w2.lastNode();
+
+        if (w1FirstNode == w2FirstNode || w1FirstNode == w2LastNode || w1LastNode == w2FirstNode
+                || w1LastNode == w2LastNode) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Checks if any way from the first collection touches any way from the
+     * second collection
+     *
+     * @param c1 first collection
+     * @param c2 second collection
+     * @return true if ways touch, false otherwise
+     */
+    public static boolean waysTouch(Collection<Way> c1, Collection<Way> c2) {
+
+        if (c1 == null || c2 == null) {
+            return false;
+        }
+
+        for (Way w1 : c1) {
+            for (Way w2 : c2) {
+                if (waysTouch(w1, w2)) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Checks if the type of the way is suitable for buses to go on it. The
+     * direction of the way (i.e. one-way roads) is irrelevant for this test.
+     *
+     * @param way
+     *            to be checked
+     * @return true if the way is suitable for buses, false otherwise.
+     */
+    public static boolean isWaySuitableForBuses(Way way) {
+        if (way.hasTag("highway", "motorway") || way.hasTag("highway", "trunk") || way.hasTag("highway", "primary")
+                || way.hasTag("highway", "secondary") || way.hasTag("highway", "tertiary")
+                || way.hasTag("highway", "unclassified") || way.hasTag("highway", "road")
+                || way.hasTag("highway", "residential") || way.hasTag("highway", "service")
+                || way.hasTag("highway", "motorway_link") || way.hasTag("highway", "trunk_link")
+                || way.hasTag("highway", "primary_link") || way.hasTag("highway", "secondary_link")
+                || way.hasTag("highway", "tertiary_link") || way.hasTag("highway", "living_street")
+                || way.hasTag("highway", "bus_guideway") || way.hasTag("highway", "road")
+                || way.hasTag("cycleway", "share_busway") || way.hasTag("cycleway", "shared_lane")) {
+            return true;
+        }
+
+        if (way.hasTag("highway", "pedestrian") && (way.hasTag("bus", "yes") || way.hasTag("psv", "yes")
+                || way.hasTag("bus", "designated") || way.hasTag("psv", "designated"))) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Checks if this way is suitable for public transport (not only for buses)
+     * @param way way
+     * @return {@code true} if this way is suitable for public transport
+     */
+    public static boolean isWaySuitableForPublicTransport(Way way) {
+
+        if (isWaySuitableForBuses(way) || way.hasTag("railway", "tram") || way.hasTag("railway", "subway")
+                || way.hasTag("railway", "subway") || way.hasTag("railway", "light_rail")
+                || way.hasTag("railway", "rail")) {
+            return true;
+        }
+
+        return false;
+
+    }
 
 }
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/utils/StopToWayAssigner.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/utils/StopToWayAssigner.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/utils/StopToWayAssigner.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.utils;
 
@@ -24,5 +25,5 @@
  * list of already assigned stops, (2) checks if the stop has a stop position,
  * (3) calculates it using proximity / growing bounding boxes
- * 
+ *
  * @author darya
  *
@@ -30,349 +31,348 @@
 public class StopToWayAssigner {
 
-	/* contains assigned stops */
-	public static HashMap<PTStop, List<Way>> stopToWay = new HashMap<>();
-
-	/*
-	 * contains all PTWays of the route relation for which this assigner was
-	 * created
-	 */
-	private HashSet<Way> ways;
-
-	/* route relation for which this StopToWayAssigner was created */
-
-	public StopToWayAssigner(List<PTWay> ptways) {
-		ways = new HashSet<Way>();
-		for (PTWay ptway : ptways) {
-			ways.addAll(ptway.getWays());
-		}
-	}
-
-	/**
-	 * Returns the PTWay for the given PTStop
-	 * 
-	 * @param stop
-	 * @return
-	 */
-	public Way get(PTStop stop) {
-
-		// 1) Search if this stop has already been assigned:
-		if (stopToWay.containsKey(stop)) {
-			List<Way> assignedWays = stopToWay.get(stop);
-			for (Way assignedWay : assignedWays) {
-				if (this.ways.contains(assignedWay)) {
-					return assignedWay;
-				}
-			}
-		}
-
-		// 2) Search if the stop has a stop position:
-		Way wayOfStopPosition = findWayForNode(stop.getStopPosition());
-		if (wayOfStopPosition != null) {
-			addAssignedWayToMap(stop, wayOfStopPosition);
-			return wayOfStopPosition;
-		}
-
-		// 3) Search if the stop has a stop_area:
-		List<OsmPrimitive> stopElements = new ArrayList<>(2);
-		if (stop.getStopPosition() != null) {
-			stopElements.add(stop.getStopPosition());
-		}
-		if (stop.getPlatform() != null) {
-			stopElements.add(stop.getPlatform());
-		}
-		Set<Relation> parents = Node.getParentRelations(stopElements);
-		for (Relation parentRelation : parents) {
-			if (parentRelation.hasTag("public_transport", "stop_area")) {
-				for (RelationMember rm : parentRelation.getMembers()) {
-					if (rm.getMember().hasTag("public_transport", "stop_position")) {
-						Way rmWay = this.findWayForNode(rm.getNode());
-						if (rmWay != null) {
-							addAssignedWayToMap(stop, rmWay);
-							return rmWay;
-						}
-					}
-				}
-			}
-		}
-
-		// 4) Search if a stop position is in the vicinity of a platform:
-		if (stop.getPlatform() != null) {
-			List<Node> potentialStopPositionList = stop.findPotentialStopPositions();
-			Node closestStopPosition = null;
-			double minDistanceSq = Double.MAX_VALUE;
-			for (Node potentialStopPosition : potentialStopPositionList) {
-				double distanceSq = potentialStopPosition.getCoor()
-						.distanceSq(stop.getPlatform().getBBox().getCenter());
-				if (distanceSq < minDistanceSq) {
-					closestStopPosition = potentialStopPosition;
-					minDistanceSq = distanceSq;
-				}
-			}
-			if (closestStopPosition != null) {
-				Way closestWay = null;
-				double minDistanceSqToWay = Double.MAX_VALUE;
-				for (Way way: this.ways) {
-					if (way.containsNode(closestStopPosition)) {
-						double distanceSq = calculateMinDistanceToSegment(new Node(stop.getPlatform().getBBox().getCenter()), way);
-						if (distanceSq < minDistanceSqToWay) {
-							closestWay = way;
-							minDistanceSqToWay = distanceSq;
-						}
-					}
-				}
-				if (closestWay != null) {
-					addAssignedWayToMap(stop, closestWay);
-					return closestWay;
-				}
-			}
-		}
-
-		// 5) Run the growing-bounding-boxes algorithm:
-		double searchRadius = 0.001;
-		while (searchRadius < 0.005) {
-
-			Way foundWay = this.findNearestWayInRadius(stop.getPlatform(), searchRadius);
-			if (foundWay != null) {
-				addAssignedWayToMap(stop, foundWay);
-				return foundWay;
-			}
-
-			foundWay = this.findNearestWayInRadius(stop.getStopPosition(), searchRadius);
-			if (foundWay != null) {
-				addAssignedWayToMap(stop, foundWay);
-				return foundWay;
-			}
-
-			searchRadius = searchRadius + 0.001;
-		}
-
-		return null;
-	}
-
-	/**
-	 * Finds the PTWay of the given stop_position by looking at its referrers
-	 * 
-	 * @param stopPosition
-	 * @return
-	 */
-	private Way findWayForNode(Node stopPosition) {
-
-		if (stopPosition == null) {
-			return null;
-		}
-
-		// search in the referrers:
-		List<OsmPrimitive> referrers = stopPosition.getReferrers();
-		for (OsmPrimitive referredPrimitive : referrers) {
-			if (referredPrimitive.getType().equals(OsmPrimitiveType.WAY)) {
-				Way referredWay = (Way) referredPrimitive;
-				if (this.ways.contains(referredWay)) {
-					return referredWay;
-				}
-			}
-		}
-
-		return null;
-	}
-
-	/**
-	 * Finds the PTWay in the given radius of the OsmPrimitive. The PTWay has to
-	 * belong to the route relation for which this StopToWayAssigner was
-	 * created. If multiple PTWays were found, the closest one is chosen.
-	 * 
-	 * @param platform
-	 * @param searchRadius
-	 * @return
-	 */
-	private Way findNearestWayInRadius(OsmPrimitive platform, double searchRadius) {
-
-		if (platform == null) {
-			return null;
-		}
-
-		LatLon platformCenter = platform.getBBox().getCenter();
-		Double ax = platformCenter.getX() - searchRadius;
-		Double bx = platformCenter.getX() + searchRadius;
-		Double ay = platformCenter.getY() - searchRadius;
-		Double by = platformCenter.getY() + searchRadius;
-		BBox platformBBox = new BBox(ax, ay, bx, by);
-
-		Set<Way> potentialWays = new HashSet<>();
-
-		Collection<Node> allNodes = platform.getDataSet().getNodes();
-		for (Node currentNode : allNodes) {
-			if (platformBBox.bounds(currentNode.getBBox())) {
-				List<OsmPrimitive> referrers = currentNode.getReferrers();
-				for (OsmPrimitive referrer : referrers) {
-					if (referrer.getType().equals(OsmPrimitiveType.WAY)) {
-						Way referrerWay = (Way) referrer;
-						if (this.ways.contains(referrerWay)) {
-							potentialWays.add(referrerWay);
-						}
-					}
-				}
-
-			}
-		}
-
-		Node platformNode = null;
-		if (platform.getType().equals(OsmPrimitiveType.NODE)) {
-			platformNode = (Node) platform;
-		} else {
-			platformNode = new Node(platform.getBBox().getCenter());
-		}
-		Way nearestWay = null;
-		Double minDistance = Double.MAX_VALUE;
-		for (Way potentialWay : potentialWays) {
-			double distance = this.calculateMinDistanceToSegment(platformNode, potentialWay);
-			if (distance < minDistance) {
-				minDistance = distance;
-				nearestWay = potentialWay;
-			}
-		}
-
-		return nearestWay;
-	}
-
-	/**
-	 * Calculates the minimum distance between a node and a way
-	 * 
-	 * @param node
-	 * @param way
-	 * @return
-	 */
-	private double calculateMinDistanceToSegment(Node node, Way way) {
-
-		double minDistance = Double.MAX_VALUE;
-
-		List<Pair<Node, Node>> waySegments = way.getNodePairs(false);
-
-		for (Pair<Node, Node> waySegment : waySegments) {
-			if (waySegment.a != node && waySegment.b != node) {
-				double distanceToLine = this.calculateDistanceToSegment(node, waySegment);
-				if (distanceToLine < minDistance) {
-					minDistance = distanceToLine;
-				}
-			}
-		}
-
-		return minDistance;
-
-	}
-
-	/**
-	 * Calculates the distance from point to segment and differentiates between
-	 * acute, right and obtuse triangles. If a triangle is acute or right, the
-	 * distance to segment is calculated as distance from point to line. If the
-	 * triangle is obtuse, the distance is calculated as the distance to the
-	 * nearest vertex of the segment.
-	 * 
-	 * @param node
-	 * @param segment
-	 * @return
-	 */
-	private double calculateDistanceToSegment(Node node, Pair<Node, Node> segment) {
-
-		if (node == segment.a || node == segment.b) {
-			return 0.0;
-		}
-
-		double lengthA = node.getCoor().distance(segment.a.getCoor());
-		double lengthB = node.getCoor().distance(segment.b.getCoor());
-		double lengthC = segment.a.getCoor().distance(segment.b.getCoor());
-
-		if (isObtuse(lengthC, lengthB, lengthA)) {
-			return lengthB;
-		}
-
-		if (isObtuse(lengthA, lengthC, lengthB)) {
-			return lengthA;
-		}
-
-		return calculateDistanceToLine(node, segment);
-	}
-
-	/**
-	 * Calculates the distance from point to line using formulas for triangle
-	 * area. Does not differentiate between acute, right and obtuse triangles
-	 * 
-	 * @param node
-	 * @param waySegment
-	 * @return
-	 */
-	private double calculateDistanceToLine(Node node, Pair<Node, Node> segment) {
-
-		/*
-		 * Let a be the triangle edge between the point and the first node of
-		 * the segment. Let b be the triangle edge between the point and the
-		 * second node of the segment. Let c be the triangle edge which is the
-		 * segment.
-		 */
-
-		double lengthA = node.getCoor().distance(segment.a.getCoor());
-		double lengthB = node.getCoor().distance(segment.b.getCoor());
-		double lengthC = segment.a.getCoor().distance(segment.b.getCoor());
-
-		// calculate triangle area using Heron's formula:
-		double p = (lengthA + lengthB + lengthC) / 2.0;
-		double triangleArea = Math.sqrt(p * (p - lengthA) * (p - lengthB) * (p - lengthC));
-
-		// calculate the distance from point to segment using the 0.5*c*h
-		// formula for triangle area:
-		return triangleArea * 2.0 / lengthC;
-	}
-
-	/**
-	 * Checks if the angle opposite of the edge c is obtuse. Uses the cosine
-	 * theorem
-	 * 
-	 * @param lengthA
-	 * @param lengthB
-	 * @param lengthC
-	 *            the triangle edge which is testes
-	 * @return true if the angle opposite of te edge c is obtuse
-	 */
-	private boolean isObtuse(double lengthA, double lengthB, double lengthC) {
-
-		/*-
-		 * Law of cosines:
-		 * c^2 = a^2 + b^2 - 2abcos
-		 * if c^2 = a^2 + b^2, it is a right triangle
-		 * if c^2 < a^2 + b^2, it is an acute triangle
-		 * if c^2 > a^2 + b^2, it is an obtuse triangle
-		 */
-
-		if (lengthC * lengthC > lengthA * lengthA + lengthB * lengthB) {
-			return true;
-		}
-
-		return false;
-	}
-
-	/**
-	 * Adds the given way to the map of assigned ways. Assumes that the given
-	 * way is not contained in the map.
-	 * 
-	 * @param stop
-	 * @param way
-	 */
-	private void addAssignedWayToMap(PTStop stop, Way way) {
-		if (stopToWay.containsKey(stop)) {
-			List<Way> assignedWays = stopToWay.get(stop);
-			assignedWays.add(way);
-		} else {
-			List<Way> assignedWays = new ArrayList<Way>();
-			assignedWays.add(way);
-			stopToWay.put(stop, assignedWays);
-		}
-	}
-
-	/**
-	 * May be needed if the correspondence between stops and ways has changed
-	 * significantly
-	 */
-	public static void reinitiate() {
-		stopToWay = new HashMap<>();
-	}
+    /* contains assigned stops */
+    public static HashMap<PTStop, List<Way>> stopToWay = new HashMap<>();
+
+    /*
+     * contains all PTWays of the route relation for which this assigner was
+     * created
+     */
+    private HashSet<Way> ways;
+
+    /* route relation for which this StopToWayAssigner was created */
+
+    public StopToWayAssigner(List<PTWay> ptways) {
+        ways = new HashSet<>();
+        for (PTWay ptway : ptways) {
+            ways.addAll(ptway.getWays());
+        }
+    }
+
+    /**
+     * Returns the PTWay for the given PTStop
+     *
+     * @param stop stop
+     * @return the PTWay for the given PTStop
+     */
+    public Way get(PTStop stop) {
+
+        // 1) Search if this stop has already been assigned:
+        if (stopToWay.containsKey(stop)) {
+            List<Way> assignedWays = stopToWay.get(stop);
+            for (Way assignedWay : assignedWays) {
+                if (this.ways.contains(assignedWay)) {
+                    return assignedWay;
+                }
+            }
+        }
+
+        // 2) Search if the stop has a stop position:
+        Way wayOfStopPosition = findWayForNode(stop.getStopPosition());
+        if (wayOfStopPosition != null) {
+            addAssignedWayToMap(stop, wayOfStopPosition);
+            return wayOfStopPosition;
+        }
+
+        // 3) Search if the stop has a stop_area:
+        List<OsmPrimitive> stopElements = new ArrayList<>(2);
+        if (stop.getStopPosition() != null) {
+            stopElements.add(stop.getStopPosition());
+        }
+        if (stop.getPlatform() != null) {
+            stopElements.add(stop.getPlatform());
+        }
+        Set<Relation> parents = Node.getParentRelations(stopElements);
+        for (Relation parentRelation : parents) {
+            if (parentRelation.hasTag("public_transport", "stop_area")) {
+                for (RelationMember rm : parentRelation.getMembers()) {
+                    if (rm.getMember().hasTag("public_transport", "stop_position")) {
+                        Way rmWay = this.findWayForNode(rm.getNode());
+                        if (rmWay != null) {
+                            addAssignedWayToMap(stop, rmWay);
+                            return rmWay;
+                        }
+                    }
+                }
+            }
+        }
+
+        // 4) Search if a stop position is in the vicinity of a platform:
+        if (stop.getPlatform() != null) {
+            List<Node> potentialStopPositionList = stop.findPotentialStopPositions();
+            Node closestStopPosition = null;
+            double minDistanceSq = Double.MAX_VALUE;
+            for (Node potentialStopPosition : potentialStopPositionList) {
+                double distanceSq = potentialStopPosition.getCoor()
+                        .distanceSq(stop.getPlatform().getBBox().getCenter());
+                if (distanceSq < minDistanceSq) {
+                    closestStopPosition = potentialStopPosition;
+                    minDistanceSq = distanceSq;
+                }
+            }
+            if (closestStopPosition != null) {
+                Way closestWay = null;
+                double minDistanceSqToWay = Double.MAX_VALUE;
+                for (Way way: this.ways) {
+                    if (way.containsNode(closestStopPosition)) {
+                        double distanceSq = calculateMinDistanceToSegment(new Node(stop.getPlatform().getBBox().getCenter()), way);
+                        if (distanceSq < minDistanceSqToWay) {
+                            closestWay = way;
+                            minDistanceSqToWay = distanceSq;
+                        }
+                    }
+                }
+                if (closestWay != null) {
+                    addAssignedWayToMap(stop, closestWay);
+                    return closestWay;
+                }
+            }
+        }
+
+        // 5) Run the growing-bounding-boxes algorithm:
+        double searchRadius = 0.001;
+        while (searchRadius < 0.005) {
+
+            Way foundWay = this.findNearestWayInRadius(stop.getPlatform(), searchRadius);
+            if (foundWay != null) {
+                addAssignedWayToMap(stop, foundWay);
+                return foundWay;
+            }
+
+            foundWay = this.findNearestWayInRadius(stop.getStopPosition(), searchRadius);
+            if (foundWay != null) {
+                addAssignedWayToMap(stop, foundWay);
+                return foundWay;
+            }
+
+            searchRadius = searchRadius + 0.001;
+        }
+
+        return null;
+    }
+
+    /**
+     * Finds the PTWay of the given stop_position by looking at its referrers
+     *
+     * @param stopPosition stop position
+     * @return the PTWay of the given stop_position by looking at its referrers
+     */
+    private Way findWayForNode(Node stopPosition) {
+
+        if (stopPosition == null) {
+            return null;
+        }
+
+        // search in the referrers:
+        List<OsmPrimitive> referrers = stopPosition.getReferrers();
+        for (OsmPrimitive referredPrimitive : referrers) {
+            if (referredPrimitive.getType().equals(OsmPrimitiveType.WAY)) {
+                Way referredWay = (Way) referredPrimitive;
+                if (this.ways.contains(referredWay)) {
+                    return referredWay;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Finds the PTWay in the given radius of the OsmPrimitive. The PTWay has to
+     * belong to the route relation for which this StopToWayAssigner was
+     * created. If multiple PTWays were found, the closest one is chosen.
+     *
+     * @param platform platform
+     * @param searchRadius search radius
+     * @return the PTWay in the given radius of the OsmPrimitive
+     */
+    private Way findNearestWayInRadius(OsmPrimitive platform, double searchRadius) {
+
+        if (platform == null) {
+            return null;
+        }
+
+        LatLon platformCenter = platform.getBBox().getCenter();
+        Double ax = platformCenter.getX() - searchRadius;
+        Double bx = platformCenter.getX() + searchRadius;
+        Double ay = platformCenter.getY() - searchRadius;
+        Double by = platformCenter.getY() + searchRadius;
+        BBox platformBBox = new BBox(ax, ay, bx, by);
+
+        Set<Way> potentialWays = new HashSet<>();
+
+        Collection<Node> allNodes = platform.getDataSet().getNodes();
+        for (Node currentNode : allNodes) {
+            if (platformBBox.bounds(currentNode.getBBox())) {
+                List<OsmPrimitive> referrers = currentNode.getReferrers();
+                for (OsmPrimitive referrer : referrers) {
+                    if (referrer.getType().equals(OsmPrimitiveType.WAY)) {
+                        Way referrerWay = (Way) referrer;
+                        if (this.ways.contains(referrerWay)) {
+                            potentialWays.add(referrerWay);
+                        }
+                    }
+                }
+
+            }
+        }
+
+        Node platformNode = null;
+        if (platform.getType().equals(OsmPrimitiveType.NODE)) {
+            platformNode = (Node) platform;
+        } else {
+            platformNode = new Node(platform.getBBox().getCenter());
+        }
+        Way nearestWay = null;
+        Double minDistance = Double.MAX_VALUE;
+        for (Way potentialWay : potentialWays) {
+            double distance = this.calculateMinDistanceToSegment(platformNode, potentialWay);
+            if (distance < minDistance) {
+                minDistance = distance;
+                nearestWay = potentialWay;
+            }
+        }
+
+        return nearestWay;
+    }
+
+    /**
+     * Calculates the minimum distance between a node and a way
+     *
+     * @param node node
+     * @param way way
+     * @return the minimum distance between a node and a way
+     */
+    private double calculateMinDistanceToSegment(Node node, Way way) {
+
+        double minDistance = Double.MAX_VALUE;
+
+        List<Pair<Node, Node>> waySegments = way.getNodePairs(false);
+
+        for (Pair<Node, Node> waySegment : waySegments) {
+            if (waySegment.a != node && waySegment.b != node) {
+                double distanceToLine = this.calculateDistanceToSegment(node, waySegment);
+                if (distanceToLine < minDistance) {
+                    minDistance = distanceToLine;
+                }
+            }
+        }
+
+        return minDistance;
+
+    }
+
+    /**
+     * Calculates the distance from point to segment and differentiates between
+     * acute, right and obtuse triangles. If a triangle is acute or right, the
+     * distance to segment is calculated as distance from point to line. If the
+     * triangle is obtuse, the distance is calculated as the distance to the
+     * nearest vertex of the segment.
+     *
+     * @param node node
+     * @param segment segment
+     * @return the distance from point to segment
+     */
+    private double calculateDistanceToSegment(Node node, Pair<Node, Node> segment) {
+
+        if (node == segment.a || node == segment.b) {
+            return 0.0;
+        }
+
+        double lengthA = node.getCoor().distance(segment.a.getCoor());
+        double lengthB = node.getCoor().distance(segment.b.getCoor());
+        double lengthC = segment.a.getCoor().distance(segment.b.getCoor());
+
+        if (isObtuse(lengthC, lengthB, lengthA)) {
+            return lengthB;
+        }
+
+        if (isObtuse(lengthA, lengthC, lengthB)) {
+            return lengthA;
+        }
+
+        return calculateDistanceToLine(node, segment);
+    }
+
+    /**
+     * Calculates the distance from point to line using formulas for triangle
+     * area. Does not differentiate between acute, right and obtuse triangles
+     *
+     * @param node node
+     * @param waySegment way segment
+     * @return the distance from point to line
+     */
+    private double calculateDistanceToLine(Node node, Pair<Node, Node> segment) {
+
+        /*
+         * Let a be the triangle edge between the point and the first node of
+         * the segment. Let b be the triangle edge between the point and the
+         * second node of the segment. Let c be the triangle edge which is the
+         * segment.
+         */
+
+        double lengthA = node.getCoor().distance(segment.a.getCoor());
+        double lengthB = node.getCoor().distance(segment.b.getCoor());
+        double lengthC = segment.a.getCoor().distance(segment.b.getCoor());
+
+        // calculate triangle area using Heron's formula:
+        double p = (lengthA + lengthB + lengthC) / 2.0;
+        double triangleArea = Math.sqrt(p * (p - lengthA) * (p - lengthB) * (p - lengthC));
+
+        // calculate the distance from point to segment using the 0.5*c*h
+        // formula for triangle area:
+        return triangleArea * 2.0 / lengthC;
+    }
+
+    /**
+     * Checks if the angle opposite of the edge c is obtuse. Uses the cosine
+     * theorem
+     *
+     * @param lengthA length A
+     * @param lengthB length B
+     * @param lengthC length C
+     * @return true if the angle opposite of the edge c is obtuse
+     */
+    private boolean isObtuse(double lengthA, double lengthB, double lengthC) {
+
+        /*-
+         * Law of cosines:
+         * c^2 = a^2 + b^2 - 2abcos
+         * if c^2 = a^2 + b^2, it is a right triangle
+         * if c^2 < a^2 + b^2, it is an acute triangle
+         * if c^2 > a^2 + b^2, it is an obtuse triangle
+         */
+
+        if (lengthC * lengthC > lengthA * lengthA + lengthB * lengthB) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Adds the given way to the map of assigned ways. Assumes that the given
+     * way is not contained in the map.
+     *
+     * @param stop stop
+     * @param way way
+     */
+    private void addAssignedWayToMap(PTStop stop, Way way) {
+        if (stopToWay.containsKey(stop)) {
+            List<Way> assignedWays = stopToWay.get(stop);
+            assignedWays.add(way);
+        } else {
+            List<Way> assignedWays = new ArrayList<>();
+            assignedWays.add(way);
+            stopToWay.put(stop, assignedWays);
+        }
+    }
+
+    /**
+     * May be needed if the correspondence between stops and ways has changed
+     * significantly
+     */
+    public static void reinitiate() {
+        stopToWay = new HashMap<>();
+    }
 
 }
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/utils/StopUtils.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/utils/StopUtils.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/utils/StopUtils.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.utils;
 
@@ -6,88 +7,88 @@
 /**
  * Utils class for stop areas
- * 
+ *
  * @author
  *
  */
-public class StopUtils {
+public final class StopUtils {
 
-	private StopUtils() {
-		// private constructor for util classes
-	}
+    private StopUtils() {
+        // private constructor for util classes
+    }
 
-	/**
-	 * Checks if a given relation is a stop_area.
-	 * 
-	 * @param r
-	 *            Relation to be checked
-	 * @return true if the relation is a stop_area, false otherwise.
-	 */
-	public static boolean isStopArea(Relation r) {
+    /**
+     * Checks if a given relation is a stop_area.
+     *
+     * @param r
+     *            Relation to be checked
+     * @return true if the relation is a stop_area, false otherwise.
+     */
+    public static boolean isStopArea(Relation r) {
 
-		if (r == null) {
-			return false;
-		}
+        if (r == null) {
+            return false;
+        }
 
-		if (r.hasTag("public_transport", "stop_area")) {
-			return true;
-		}
-		return false;
-	}
+        if (r.hasTag("public_transport", "stop_area")) {
+            return true;
+        }
+        return false;
+    }
 
-	/**
-	 * Checks if a given object is a stop_position.
-	 * 
-	 * @param r
-	 *            Relation to be checked
-	 * @return true if the object is a stop_position, false otherwise.
-	 */
-	public static boolean verifyStopAreaStopPosition(OsmPrimitive rm) {
+    /**
+     * Checks if a given object is a stop_position.
+     *
+     * @param r
+     *            Relation to be checked
+     * @return true if the object is a stop_position, false otherwise.
+     */
+    public static boolean verifyStopAreaStopPosition(OsmPrimitive rm) {
 
-		if (rm == null) {
-			return false;
-		}
+        if (rm == null) {
+            return false;
+        }
 
-		if (rm.hasTag("public_transport", "stop_position")) {
-			return true;
-		}
-		return false;
-	}
+        if (rm.hasTag("public_transport", "stop_position")) {
+            return true;
+        }
+        return false;
+    }
 
-	/**
-	 * Checks if a given object is a platform.
-	 * 
-	 * @param r
-	 *            Relation to be checked
-	 * @return true if the object is a platform, false otherwise.
-	 */
-	public static boolean verifyStopAreaPlatform(OsmPrimitive rm) {
+    /**
+     * Checks if a given object is a platform.
+     *
+     * @param r
+     *            Relation to be checked
+     * @return true if the object is a platform, false otherwise.
+     */
+    public static boolean verifyStopAreaPlatform(OsmPrimitive rm) {
 
-		if (rm == null) {
-			return false;
-		}
+        if (rm == null) {
+            return false;
+        }
 
-		if (rm.hasTag("public_transport", "platform") || rm.hasTag("highway", "bus_stop")
-				|| rm.hasTag("highway", "platform") || rm.hasTag("railway", "platform")) {
-			return true;
-		}
-		return false;
-	}
+        if (rm.hasTag("public_transport", "platform") || rm.hasTag("highway", "bus_stop")
+                || rm.hasTag("highway", "platform") || rm.hasTag("railway", "platform")) {
+            return true;
+        }
+        return false;
+    }
 
-	/**
-	 * Checks if a given object is part of an stop area relation
-	 * 
-	 * @param r
-	 *            Object to be checked
-	 * @return true if the object part of stop area relation, false otherwise.
-	 */
-	public static boolean verifyIfMemberOfStopArea(OsmPrimitive member) {
+    /**
+     * Checks if a given object is part of an stop area relation
+     *
+     * @param r
+     *            Object to be checked
+     * @return true if the object part of stop area relation, false otherwise.
+     */
+    public static boolean verifyIfMemberOfStopArea(OsmPrimitive member) {
 
-		for (Relation parentRelation : OsmPrimitive.getFilteredList(member.getReferrers(), Relation.class)) {
-			if (StopUtils.isStopArea(parentRelation)) {
-				return true;
-			}
-		}
-		return false;
-	}
+        for (Relation parentRelation : OsmPrimitive.getFilteredList(member.getReferrers(), Relation.class)) {
+            if (StopUtils.isStopArea(parentRelation)) {
+                return true;
+            }
+        }
+        return false;
+    }
 
 }
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/Checker.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/Checker.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/Checker.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.validation;
 
@@ -25,5 +26,5 @@
 /**
  * Represents tests and fixed of the PT_Assistant plugin
- * 
+ *
  * @author darya
  *
@@ -31,177 +32,172 @@
 public abstract class Checker {
 
-	// test which created this WayChecker:
-	protected final Test test;
-
-	// node that is checked:
-	protected Node node;
-
-	// relation that is checked:
-	protected Relation relation;
-
-	// stores all found errors:
-	protected ArrayList<TestError> errors = new ArrayList<>();
-
-	protected Checker(Node node, Test test) {
-		this.node = node;
-		this.test = test;
-	}
-
-	protected Checker(Relation relation, Test test) {
-		this.relation = relation;
-		this.test = test;
-	}
-
-	/**
-	 * Returns errors
-	 */
-	public List<TestError> getErrors() {
-
-		return errors;
-	}
-
-	/**
-	 * Returns a list of stop-related route relation members with corrected
-	 * roles (if necessary)
-	 * 
-	 * @return list of stop-related route relation members
-	 */
-	protected static List<RelationMember> listStopMembers(Relation r) {
-
-		List<RelationMember> resultList = new ArrayList<>();
-
-		for (RelationMember rm : r.getMembers()) {
-
-			if (RouteUtils.isPTStop(rm)) {
-
-				if (rm.getMember().hasTag("public_transport", "stop_position")) {
-					if (!rm.hasRole("stop") && !rm.hasRole("stop_entry_only") && !rm.hasRole("stop_exit_only")) {
-						RelationMember newMember = new RelationMember("stop", rm.getMember());
-						resultList.add(newMember);
-					} else {
-						resultList.add(rm);
-					}
-				} else { // if platform
-					if (!rm.hasRole("platform") && !rm.hasRole("platform_entry_only")
-							&& !rm.hasRole("platform_exit_only")) {
-						RelationMember newMember = new RelationMember("platform", rm.getMember());
-						resultList.add(newMember);
-					} else {
-						resultList.add(rm);
-					}
-				}
-
-			}
-		}
-
-		return resultList;
-	}
-
-	/**
-	 * Returns a list of other (not stop-related) route relation members with
-	 * corrected roles (if necessary)
-	 * 
-	 * @return list of other (not stop-related) route relation members
-	 */
-	protected static List<RelationMember> listNotStopMembers(Relation r) {
-
-		List<RelationMember> resultList = new ArrayList<RelationMember>();
-
-		for (RelationMember rm : r.getMembers()) {
-
-			if (!RouteUtils.isPTStop(rm)) {
-
-				if (rm.hasRole("forward") || rm.hasRole("backward")) {
-					RelationMember newMember = new RelationMember("", rm.getMember());
-					resultList.add(newMember);
-				} else {
-
-					resultList.add(rm);
-
-				}
-			}
-
-		}
-
-		return resultList;
-	}
-
-	/**
-	 * 
-	 * @param testError
-	 * @return
-	 */
-	protected static Command fixErrorByZooming(TestError testError) {
-
-		if (testError.getCode() != PTAssistantValidatorTest.ERROR_CODE_STOP_BY_STOP
-				&& testError.getCode() != PTAssistantValidatorTest.ERROR_CODE_DIRECTION
-				&& testError.getCode() != PTAssistantValidatorTest.ERROR_CODE_CONSTRUCTION
-				&& testError.getCode() != PTAssistantValidatorTest.ERROR_CODE_ROAD_TYPE) {
-			return null;
-		}
-
-		Collection<? extends OsmPrimitive> primitives = testError.getPrimitives();
-		Relation originalRelation = (Relation) primitives.iterator().next();
-		ArrayList<OsmPrimitive> primitivesToZoom = new ArrayList<>();
-		for (Object primitiveToZoom : testError.getHighlighted()) {
-			primitivesToZoom.add((OsmPrimitive) primitiveToZoom);
-		}
-
-		SelectCommand command = new SelectCommand(primitivesToZoom);
-
-		List<OsmDataLayer> listOfLayers = Main.getLayerManager().getLayersOfType(OsmDataLayer.class);
-		for (OsmDataLayer osmDataLayer : listOfLayers) {
-			if (osmDataLayer.data == originalRelation.getDataSet()) {
-
-				final OsmDataLayer layerParameter = osmDataLayer;
-				final Relation relationParameter = originalRelation;
-				final Collection<OsmPrimitive> zoomParameter = primitivesToZoom;
-
-				if (SwingUtilities.isEventDispatchThread()) {
-
-					showRelationEditorAndZoom(layerParameter, relationParameter, zoomParameter);
-
-				} else {
-
-					SwingUtilities.invokeLater(new Runnable() {
-						@Override
-						public void run() {
-
-							showRelationEditorAndZoom(layerParameter, relationParameter, zoomParameter);
-
-						}
-					});
-
-				}
-
-				return command;
-			}
-		}
-
-		return null;
-
-	}
-
-	private static void showRelationEditorAndZoom(OsmDataLayer layer, Relation r, Collection<OsmPrimitive> primitives) {
-
-		// zoom to problem:
-		AutoScaleAction.zoomTo(primitives);
-
-		// put stop-related members to the front and edit roles if necessary:
-		List<RelationMember> sortedRelationMembers = listStopMembers(r);
-		sortedRelationMembers.addAll(listNotStopMembers(r));
-		r.setMembers(sortedRelationMembers);
-
-		// create editor:
-		GenericRelationEditor editor = (GenericRelationEditor) RelationEditor.getEditor(layer, r,
-				r.getMembersFor(primitives));
-
-		// open editor:
-		editor.setVisible(true);
-
-		// make the current relation purple in the pt_assistant layer:
-		PTAssistantLayer.getLayer().repaint(r);
-
-	}
+    // test which created this WayChecker:
+    protected final Test test;
+
+    // node that is checked:
+    protected Node node;
+
+    // relation that is checked:
+    protected Relation relation;
+
+    // stores all found errors:
+    protected ArrayList<TestError> errors = new ArrayList<>();
+
+    protected Checker(Node node, Test test) {
+        this.node = node;
+        this.test = test;
+    }
+
+    protected Checker(Relation relation, Test test) {
+        this.relation = relation;
+        this.test = test;
+    }
+
+    /**
+     * Returns errors
+     */
+    public List<TestError> getErrors() {
+
+        return errors;
+    }
+
+    /**
+     * Returns a list of stop-related route relation members with corrected
+     * roles (if necessary)
+     *
+     * @return list of stop-related route relation members
+     */
+    protected static List<RelationMember> listStopMembers(Relation r) {
+
+        List<RelationMember> resultList = new ArrayList<>();
+
+        for (RelationMember rm : r.getMembers()) {
+
+            if (RouteUtils.isPTStop(rm)) {
+
+                if (rm.getMember().hasTag("public_transport", "stop_position")) {
+                    if (!rm.hasRole("stop") && !rm.hasRole("stop_entry_only") && !rm.hasRole("stop_exit_only")) {
+                        RelationMember newMember = new RelationMember("stop", rm.getMember());
+                        resultList.add(newMember);
+                    } else {
+                        resultList.add(rm);
+                    }
+                } else { // if platform
+                    if (!rm.hasRole("platform") && !rm.hasRole("platform_entry_only")
+                            && !rm.hasRole("platform_exit_only")) {
+                        RelationMember newMember = new RelationMember("platform", rm.getMember());
+                        resultList.add(newMember);
+                    } else {
+                        resultList.add(rm);
+                    }
+                }
+
+            }
+        }
+
+        return resultList;
+    }
+
+    /**
+     * Returns a list of other (not stop-related) route relation members with
+     * corrected roles (if necessary)
+     *
+     * @return list of other (not stop-related) route relation members
+     */
+    protected static List<RelationMember> listNotStopMembers(Relation r) {
+
+        List<RelationMember> resultList = new ArrayList<>();
+
+        for (RelationMember rm : r.getMembers()) {
+
+            if (!RouteUtils.isPTStop(rm)) {
+
+                if (rm.hasRole("forward") || rm.hasRole("backward")) {
+                    RelationMember newMember = new RelationMember("", rm.getMember());
+                    resultList.add(newMember);
+                } else {
+
+                    resultList.add(rm);
+
+                }
+            }
+
+        }
+
+        return resultList;
+    }
+
+    protected static Command fixErrorByZooming(TestError testError) {
+
+        if (testError.getCode() != PTAssistantValidatorTest.ERROR_CODE_STOP_BY_STOP
+                && testError.getCode() != PTAssistantValidatorTest.ERROR_CODE_DIRECTION
+                && testError.getCode() != PTAssistantValidatorTest.ERROR_CODE_CONSTRUCTION
+                && testError.getCode() != PTAssistantValidatorTest.ERROR_CODE_ROAD_TYPE) {
+            return null;
+        }
+
+        Collection<? extends OsmPrimitive> primitives = testError.getPrimitives();
+        Relation originalRelation = (Relation) primitives.iterator().next();
+        ArrayList<OsmPrimitive> primitivesToZoom = new ArrayList<>();
+        for (Object primitiveToZoom : testError.getHighlighted()) {
+            primitivesToZoom.add((OsmPrimitive) primitiveToZoom);
+        }
+
+        SelectCommand command = new SelectCommand(primitivesToZoom);
+
+        List<OsmDataLayer> listOfLayers = Main.getLayerManager().getLayersOfType(OsmDataLayer.class);
+        for (OsmDataLayer osmDataLayer : listOfLayers) {
+            if (osmDataLayer.data == originalRelation.getDataSet()) {
+
+                final OsmDataLayer layerParameter = osmDataLayer;
+                final Relation relationParameter = originalRelation;
+                final Collection<OsmPrimitive> zoomParameter = primitivesToZoom;
+
+                if (SwingUtilities.isEventDispatchThread()) {
+
+                    showRelationEditorAndZoom(layerParameter, relationParameter, zoomParameter);
+
+                } else {
+
+                    SwingUtilities.invokeLater(new Runnable() {
+                        @Override
+                        public void run() {
+
+                            showRelationEditorAndZoom(layerParameter, relationParameter, zoomParameter);
+
+                        }
+                    });
+
+                }
+
+                return command;
+            }
+        }
+
+        return null;
+
+    }
+
+    private static void showRelationEditorAndZoom(OsmDataLayer layer, Relation r, Collection<OsmPrimitive> primitives) {
+
+        // zoom to problem:
+        AutoScaleAction.zoomTo(primitives);
+
+        // put stop-related members to the front and edit roles if necessary:
+        List<RelationMember> sortedRelationMembers = listStopMembers(r);
+        sortedRelationMembers.addAll(listNotStopMembers(r));
+        r.setMembers(sortedRelationMembers);
+
+        // create editor:
+        GenericRelationEditor editor = (GenericRelationEditor) RelationEditor.getEditor(layer, r,
+                r.getMembersFor(primitives));
+
+        // open editor:
+        editor.setVisible(true);
+
+        // make the current relation purple in the pt_assistant layer:
+        PTAssistantLayer.getLayer().repaint(r);
+
+    }
 
 }
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 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/NodeChecker.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.validation;
 
@@ -26,152 +27,147 @@
 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
-	 * 
-	 * @param n
-	 */
-	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);
-		TestError e = new TestError(this.test, Severity.WARNING, tr("PT: Stop_position is not part of a way"),
-				PTAssistantValidatorTest.ERROR_CODE_SOLITARY_STOP_POSITION, primitives);
-		errors.add(e);
+        List<OsmPrimitive> primitives = new ArrayList<>(1);
+        primitives.add(node);
+        TestError e = new TestError(this.test, Severity.WARNING, tr("PT: Stop_position is not part of a way"),
+                PTAssistantValidatorTest.ERROR_CODE_SOLITARY_STOP_POSITION, primitives);
+        errors.add(e);
 
-	}
+    }
 
-	/**
-	 * Checks if the given platform node belongs to any way
-	 * 
-	 * @param n
-	 */
-	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)) {
-					TestError e = new TestError(this.test, Severity.WARNING,
-							tr("PT: Platform should not be part of a way"),
-							PTAssistantValidatorTest.ERROR_CODE_PLATFORM_PART_OF_HIGHWAY, primitives);
-					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)) {
+                    TestError e = new TestError(this.test, Severity.WARNING,
+                            tr("PT: Platform should not be part of a way"),
+                            PTAssistantValidatorTest.ERROR_CODE_PLATFORM_PART_OF_HIGHWAY, primitives);
+                    errors.add(e);
+                    return;
+                }
+            }
+        }
+    }
 
-	/**
-	 * Checks if the given stop_position node belongs to any stop_area relation
-	 * @author xamanu
-	 * @param n
-	 */
-	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);
-			TestError e = new TestError(this.test, Severity.WARNING,
-					tr("PT: Stop position or platform is not part of a stop area relation"),
-					PTAssistantValidatorTest.ERROR_CODE_NOT_PART_OF_STOP_AREA, primitives);
-			errors.add(e);
-		}
-	}
+            List<OsmPrimitive> primitives = new ArrayList<>(1);
+            primitives.add(node);
+            TestError e = new TestError(this.test, Severity.WARNING,
+                    tr("PT: Stop position or platform is not part of a stop area relation"),
+                    PTAssistantValidatorTest.ERROR_CODE_NOT_PART_OF_STOP_AREA, primitives);
+            errors.add(e);
+        }
+    }
 
-	/**
-	 * Fixes errors: solitary stop position and platform which is part of a way.
-	 * Asks the user first.
-	 * 
-	 * @param testError
-	 * @return
-	 */
-	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 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/PTAssistantValidatorTest.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.validation;
 
@@ -40,518 +41,516 @@
 public class PTAssistantValidatorTest extends Test {
 
-	public static final int ERROR_CODE_SORTING = 3711;
-	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_RELAITON_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;
-
-	private PTAssistantLayer layer;
-
-	public PTAssistantValidatorTest() {
-		super(tr("Public Transport Assistant tests"),
-				tr("Check if route relations are compatible with public transport version 2"));
-
-		layer = PTAssistantLayer.getLayer();
-		DataSet.addSelectionListener(layer);
-
-	}
-
-	@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", true) == 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", true) == 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", true) == 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.isTwoDirectionRoute(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
-	 */
-	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
-	 */
-	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) {
-				sortingErrorFound = true;
-				break;
-			}
-		}
-		if (!sortingErrorFound) {
-			segmentChecker.performStopByStopTest();
-			segmentChecker.findFixes();
-		}
-		
-		for (TestError error: segmentChecker.getErrors()) {
-			if (error.getCode() != PTAssistantValidatorTest.ERROR_CODE_RELAITON_MEMBER_ROLES) {
-				this.errors.add(error);
-			}
-		}
-	}
-
-	/**
-	 * 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() == PTAssistantValidatorTest.ERROR_CODE_SOLITARY_STOP_POSITION
-				|| testError.getCode() == PTAssistantValidatorTest.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();
-			this.layer.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) {
-			commands.add(WayChecker.fixErrorByZooming(testError));
-		}
-
-		if (testError.getCode() == ERROR_CODE_DIRECTION) {
-			commands.add(WayChecker.fixErrorByZooming(testError));
-
-		}
-
-		if (testError.getCode() == ERROR_CODE_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).
-	 * 
-	 * @return
-	 */
-	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) {
-		layer.addFixVariants(fixVariants);
-	}
-
-	public void clearFixVariants() {
-		layer.clearFixVariants();
-	}
-
-	public List<PTWay> getFixVariant(Character c) {
-		return layer.getFixVariant(c);
-	}
-
-	@SuppressWarnings("unused")
-	private void performDummyTest(Relation r) {
-		List<Relation> primitives = new ArrayList<>(1);
-		primitives.add(r);
-		errors.add(
-				new TestError(this, Severity.WARNING, tr("PT: dummy test warning"), ERROR_CODE_DIRECTION, primitives));
-	}
+    public static final int ERROR_CODE_SORTING = 3711;
+    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_RELAITON_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;
+
+    private PTAssistantLayer layer;
+
+    public PTAssistantValidatorTest() {
+        super(tr("Public Transport Assistant tests"),
+                tr("Check if route relations are compatible with public transport version 2"));
+
+        layer = PTAssistantLayer.getLayer();
+        DataSet.addSelectionListener(layer);
+
+    }
+
+    @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", true) == 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", true) == 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", true) == 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.isTwoDirectionRoute(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) {
+                sortingErrorFound = true;
+                break;
+            }
+        }
+        if (!sortingErrorFound) {
+            segmentChecker.performStopByStopTest();
+            segmentChecker.findFixes();
+        }
+
+        for (TestError error: segmentChecker.getErrors()) {
+            if (error.getCode() != PTAssistantValidatorTest.ERROR_CODE_RELAITON_MEMBER_ROLES) {
+                this.errors.add(error);
+            }
+        }
+    }
+
+    /**
+     * 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() == PTAssistantValidatorTest.ERROR_CODE_SOLITARY_STOP_POSITION
+                || testError.getCode() == PTAssistantValidatorTest.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();
+            this.layer.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) {
+            commands.add(WayChecker.fixErrorByZooming(testError));
+        }
+
+        if (testError.getCode() == ERROR_CODE_DIRECTION) {
+            commands.add(WayChecker.fixErrorByZooming(testError));
+
+        }
+
+        if (testError.getCode() == ERROR_CODE_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) {
+        layer.addFixVariants(fixVariants);
+    }
+
+    public void clearFixVariants() {
+        layer.clearFixVariants();
+    }
+
+    public List<PTWay> getFixVariant(Character c) {
+        return layer.getFixVariant(c);
+    }
+
+    @SuppressWarnings("unused")
+    private void performDummyTest(Relation r) {
+        List<Relation> primitives = new ArrayList<>(1);
+        primitives.add(r);
+        errors.add(
+                new TestError(this, Severity.WARNING, tr("PT: dummy test warning"), ERROR_CODE_DIRECTION, primitives));
+    }
 
 }
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 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/RouteChecker.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.validation;
 
@@ -23,5 +24,5 @@
 /**
  * Performs tests of a route at the level of the whole route: sorting test
- * 
+ *
  * @author darya
  *
@@ -29,146 +30,146 @@
 public class RouteChecker extends Checker {
 
-	private boolean hasGap;
+    private boolean hasGap;
 
-	List<RelationMember> sortedMembers;
+    List<RelationMember> sortedMembers;
 
-	public RouteChecker(Relation relation, Test test) {
+    public RouteChecker(Relation relation, Test test) {
 
-		super(relation, test);
+        super(relation, test);
 
-		this.hasGap = false;
+        this.hasGap = false;
 
-	}
+    }
 
-	protected void performSortingTest() {
+    protected void performSortingTest() {
 
-		final List<RelationMember> waysToCheck = new ArrayList<>();
-		for (RelationMember rm : relation.getMembers()) {
+        final List<RelationMember> waysToCheck = new ArrayList<>();
+        for (RelationMember rm : relation.getMembers()) {
 
-			if (RouteUtils.isPTWay(rm) && rm.getType().equals(OsmPrimitiveType.WAY)) {
-				waysToCheck.add(rm);
-			}
-		}
+            if (RouteUtils.isPTWay(rm) && rm.getType().equals(OsmPrimitiveType.WAY)) {
+                waysToCheck.add(rm);
+            }
+        }
 
-		if (waysToCheck.isEmpty()) {
-			return;
-		}
+        if (waysToCheck.isEmpty()) {
+            return;
+        }
 
-		if (hasGap(waysToCheck)) {
+        if (hasGap(waysToCheck)) {
 
-			this.hasGap = true;
+            this.hasGap = true;
 
-			RelationSorter sorter = new RelationSorter();
-			sortedMembers = sorter.sortMembers(waysToCheck);
+            RelationSorter sorter = new RelationSorter();
+            sortedMembers = sorter.sortMembers(waysToCheck);
 
-			if (!hasGap(sortedMembers)) {
-				TestError e = new TestError(this.test, Severity.WARNING,
-						tr("PT: Route contains a gap that can be fixed by sorting"),
-						PTAssistantValidatorTest.ERROR_CODE_SORTING, relation);
-				this.errors.add(e);
+            if (!hasGap(sortedMembers)) {
+                TestError e = new TestError(this.test, Severity.WARNING,
+                        tr("PT: Route contains a gap that can be fixed by sorting"),
+                        PTAssistantValidatorTest.ERROR_CODE_SORTING, relation);
+                this.errors.add(e);
 
-			}
+            }
 
-		}
+        }
 
-	}
+    }
 
-	/**
-	 * Checks if there is a gap for a given list of ways. It does not check if
-	 * the way actually stands for a public transport platform - that should be
-	 * checked beforehand.
-	 * 
-	 * @param waysToCheck
-	 * @return true if has gap (in the sense of continuity of ways in the
-	 *         Relation Editor), false otherwise
-	 */
-	private boolean hasGap(List<RelationMember> waysToCheck) {
-		WayConnectionTypeCalculator connectionTypeCalculator = new WayConnectionTypeCalculator();
-		final List<WayConnectionType> links = connectionTypeCalculator.updateLinks(waysToCheck);
-		for (int i = 0; i < links.size(); i++) {
-			final WayConnectionType link = links.get(i);
-			final boolean hasError = !(i == 0 || link.linkPrev) || !(i == links.size() - 1 || link.linkNext)
-					|| link.direction == null || WayConnectionType.Direction.NONE.equals(link.direction);
-			if (hasError) {
-				return true;
+    /**
+     * Checks if there is a gap for a given list of ways. It does not check if
+     * the way actually stands for a public transport platform - that should be
+     * checked beforehand.
+     *
+     * @param waysToCheck ways to check
+     * @return true if has gap (in the sense of continuity of ways in the
+     *         Relation Editor), false otherwise
+     */
+    private boolean hasGap(List<RelationMember> waysToCheck) {
+        WayConnectionTypeCalculator connectionTypeCalculator = new WayConnectionTypeCalculator();
+        final List<WayConnectionType> links = connectionTypeCalculator.updateLinks(waysToCheck);
+        for (int i = 0; i < links.size(); i++) {
+            final WayConnectionType link = links.get(i);
+            final boolean hasError = !(i == 0 || link.linkPrev) || !(i == links.size() - 1 || link.linkNext)
+                    || link.direction == null || WayConnectionType.Direction.NONE.equals(link.direction);
+            if (hasError) {
+                return true;
 
-			}
-		}
+            }
+        }
 
-		return false;
-	}
+        return false;
+    }
 
-	public List<RelationMember> getSortedMembers() {
+    public List<RelationMember> getSortedMembers() {
 
-		return sortedMembers;
+        return sortedMembers;
 
-	}
+    }
 
-	public boolean getHasGap() {
+    public boolean getHasGap() {
 
-		return this.hasGap;
+        return this.hasGap;
 
-	}
-	
-	protected static Command fixSortingError(TestError testError) {
-		if (testError.getCode() != PTAssistantValidatorTest.ERROR_CODE_SORTING) {
-			return null;
-		}
+    }
 
-		Collection<? extends OsmPrimitive> primitives = testError.getPrimitives();
-		Relation originalRelation = (Relation) primitives.iterator().next();
+    protected static Command fixSortingError(TestError testError) {
+        if (testError.getCode() != PTAssistantValidatorTest.ERROR_CODE_SORTING) {
+            return null;
+        }
 
-		// separate ways from stops (because otherwise the order of
-		// stops/platforms can be messed up by the sorter:
-		List<RelationMember> members = originalRelation.getMembers();
-		final List<RelationMember> stops = new ArrayList<>();
-		final List<RelationMember> ways = new ArrayList<>();
-		for (RelationMember member : members) {
-			if (RouteUtils.isPTWay(member)) {
-				if (member.getRole().equals("")) {
-					ways.add(member);
-				} else {
-					RelationMember modifiedMember = new RelationMember("", member.getWay());
-					ways.add(modifiedMember);
-				}
+        Collection<? extends OsmPrimitive> primitives = testError.getPrimitives();
+        Relation originalRelation = (Relation) primitives.iterator().next();
 
-			} else { // stops:
-				if (member.getRole().equals("stop_positon")) {
-					// it is not expected that stop_positions could
-					// be relations
-					if (member.getType().equals(OsmPrimitiveType.NODE)) {
-						RelationMember modifiedMember = new RelationMember("stop", member.getNode());
-						stops.add(modifiedMember);
-					} else { // if it is a primitive of type way:
-						RelationMember modifiedMember = new RelationMember("stop", member.getWay());
-						stops.add(modifiedMember);
-					}
-				} else { // if it is not a stop_position:
-					stops.add(member);
-				}
+        // separate ways from stops (because otherwise the order of
+        // stops/platforms can be messed up by the sorter:
+        List<RelationMember> members = originalRelation.getMembers();
+        final List<RelationMember> stops = new ArrayList<>();
+        final List<RelationMember> ways = new ArrayList<>();
+        for (RelationMember member : members) {
+            if (RouteUtils.isPTWay(member)) {
+                if (member.getRole().equals("")) {
+                    ways.add(member);
+                } else {
+                    RelationMember modifiedMember = new RelationMember("", member.getWay());
+                    ways.add(modifiedMember);
+                }
 
-			}
-		}
+            } else { // stops:
+                if (member.getRole().equals("stop_positon")) {
+                    // it is not expected that stop_positions could
+                    // be relations
+                    if (member.getType().equals(OsmPrimitiveType.NODE)) {
+                        RelationMember modifiedMember = new RelationMember("stop", member.getNode());
+                        stops.add(modifiedMember);
+                    } else { // if it is a primitive of type way:
+                        RelationMember modifiedMember = new RelationMember("stop", member.getWay());
+                        stops.add(modifiedMember);
+                    }
+                } else { // if it is not a stop_position:
+                    stops.add(member);
+                }
 
-		// sort the ways:
-		RelationSorter sorter = new RelationSorter();
-		List<RelationMember> sortedWays = sorter.sortMembers(ways);
+            }
+        }
 
-		// create a new relation to pass to the command:
-		Relation sortedRelation = new Relation(originalRelation);
-		List<RelationMember> sortedRelationMembers = new ArrayList<>(members.size());
-		for (RelationMember rm : stops) {
-			sortedRelationMembers.add(rm);
-		}
-		for (RelationMember rm : sortedWays) {
-			sortedRelationMembers.add(rm);
-		}
-		sortedRelation.setMembers(sortedRelationMembers);
+        // sort the ways:
+        RelationSorter sorter = new RelationSorter();
+        List<RelationMember> sortedWays = sorter.sortMembers(ways);
 
-		ChangeCommand changeCommand = new ChangeCommand(originalRelation, sortedRelation);
+        // create a new relation to pass to the command:
+        Relation sortedRelation = new Relation(originalRelation);
+        List<RelationMember> sortedRelationMembers = new ArrayList<>(members.size());
+        for (RelationMember rm : stops) {
+            sortedRelationMembers.add(rm);
+        }
+        for (RelationMember rm : sortedWays) {
+            sortedRelationMembers.add(rm);
+        }
+        sortedRelation.setMembers(sortedRelationMembers);
 
-		return changeCommand;
+        ChangeCommand changeCommand = new ChangeCommand(originalRelation, sortedRelation);
 
-	}
+        return changeCommand;
+
+    }
 
 }
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 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/SegmentChecker.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.validation;
 
@@ -40,5 +41,5 @@
  * Performs tests of a route at the level of route segments (the stop-by-stop
  * approach).
- * 
+ *
  * @author darya
  *
@@ -46,1021 +47,1016 @@
 public class SegmentChecker extends Checker {
 
-	/* PTRouteSegments that have been validated and are correct */
-	private static List<PTRouteSegment> correctSegments = new ArrayList<PTRouteSegment>();
-
-	/* PTRouteSegments that are wrong, stored in case the user calls the fix */
-	private static HashMap<TestError, PTRouteSegment> wrongSegments = new HashMap<TestError, PTRouteSegment>();
-
-	/* 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());
-			TestError e = new TestError(this.test, Severity.WARNING, tr("PT: Relation member roles do not match tags"),
-					PTAssistantValidatorTest.ERROR_CODE_RELAITON_MEMBER_ROLES, primitives, highlighted);
-			this.errors.add(e);
-		}
-
-		this.assigner = new StopToWayAssigner(manager.getPTWays());
-
-	}
-
-	/**
-	 * Returns the number of route segments that have been already successfully
-	 * verified
-	 * 
-	 * @return
-	 */
-	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 synchronized static void addCorrectSegment(PTRouteSegment segment) {
-		for (PTRouteSegment correctSegment : correctSegments) {
-			if (correctSegment.equalsRouteSegment(segment)) {
-				return;
-			}
-		}
-		correctSegments.add(segment);
-	}
-	
-	/**
-	 * Used for unit tests
-	 * @param error
-	 * @return
-	 */
-	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());
-				TestError e = new TestError(this.test, Severity.WARNING,
-						tr("PT: Route should start and end with a stop_position"),
-						PTAssistantValidatorTest.ERROR_CODE_END_STOP, primitives, highlighted);
-				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);
-
-				TestError e = new TestError(this.test, Severity.WARNING, tr("PT: First or last way needs to be split"),
-						PTAssistantValidatorTest.ERROR_CODE_SPLIT_WAY, primitives, highlighted);
-				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());
-				TestError e = new TestError(this.test, Severity.WARNING, tr("PT: First or last way needs to be split"),
-						PTAssistantValidatorTest.ERROR_CODE_SPLIT_WAY, primitives, highlighted);
-				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;
-		}
-
-		// 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 (!this.errors.isEmpty() && this.errors.get(this.errors.size() - 1).getHighlighted().size() == 1
-						&& this.errors.get(this.errors.size() - 1).getHighlighted().iterator().next() == 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);
-					TestError e = new TestError(this.test, Severity.WARNING, tr("PT: Problem in the route segment"),
-							PTAssistantValidatorTest.ERROR_CODE_STOP_BY_STOP, primitives, highlighted);
-					this.errors.add(e);
-					PTRouteSegment routeSegment = new PTRouteSegment(startStop, endStop, segmentWays, relation);
-					wrongSegments.put(e, routeSegment);
-				}
-				continue;
-			}
-
-			boolean sortingCorrect = existingWaySortingIsCorrect(segmentWays.get(0), firstNode,
-					segmentWays.get(segmentWays.size() - 1));
-			if (sortingCorrect) {
-				PTRouteSegment routeSegment = new PTRouteSegment(startStop, endStop, segmentWays, relation);
-				addCorrectSegment(routeSegment);
-			} else {
-				PTRouteSegment routeSegment = new PTRouteSegment(startStop, endStop, segmentWays, relation);
-				TestError error = this.errors.get(this.errors.size() - 1);
-				wrongSegments.put(error, routeSegment);
-			}
-		}
-	}
-
-	/**
-	 * Creates a TestError and adds it to the list of errors for a stop that is
-	 * not served.
-	 * 
-	 * @param 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);
-		TestError e = new TestError(this.test, Severity.WARNING, tr("PT: Stop not served"),
-				PTAssistantValidatorTest.ERROR_CODE_STOP_NOT_SERVED, primitives, highlighted);
-		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;
-
-	}
-
-	/**
-	 * 
-	 * @param node
-	 * @return
-	 */
-	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
-	 * @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 true if the sorting is correct, false otherwise.
-	 */
-	private boolean existingWaySortingIsCorrect(PTWay start, Node startWayPreviousNodeInDirectionOfTravel, PTWay end) {
-
-		if (start == end) {
-			// if both PTStops are on the same PTWay
-			return true;
-		}
-
-		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) {
-					List<Relation> primitives = new ArrayList<>(1);
-					primitives.add(relation);
-					List<OsmPrimitive> highlighted = new ArrayList<>();
-					highlighted.addAll(current.getWays());
-					TestError e = new TestError(this.test, Severity.WARNING, tr("PT: Problem in the route segment"),
-							PTAssistantValidatorTest.ERROR_CODE_STOP_BY_STOP, primitives, highlighted);
-					this.errors.add(e);
-					return false;
-				}
-			} 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)) {
-					List<Relation> primitives = new ArrayList<>(1);
-					primitives.add(relation);
-					List<OsmPrimitive> highlighted = new ArrayList<>();
-
-					highlighted.addAll(current.getWays());
-
-					TestError e = new TestError(this.test, Severity.WARNING, tr("PT: Problem in the route segment"),
-							PTAssistantValidatorTest.ERROR_CODE_STOP_BY_STOP, primitives, highlighted);
-					this.errors.add(e);
-					return false;
-
-				}
-			}
-
-			current = nextPTWayAccortingToExistingSorting;
-
-		}
-
-		return true;
-	}
-
-	/**
-	 * Will return the same node if the way is an unsplit roundabout
-	 * 
-	 * @param way
-	 * @param node
-	 * @return
-	 */
-	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
-	 * @param node
-	 * @return
-	 */
-	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 way
-	 * @param nodeInDirectionOfTravel
-	 * @return
-	 */
-	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. Modifies the messages in the test
-	 * error according to the availability of automatic fixes.
-	 */
-	protected void findFixes() {
-
-		for (TestError error : wrongSegments.keySet()) {
-			// look for fixes using sorting and removing:
-			findFix(error);
-
-			// change the error code based on the availability of fixes:
-			PTRouteSegment wrongSegment = wrongSegments.get(error);
-			List<PTRouteSegment> correctSegmentsForThisError = new ArrayList<>();
-			for (PTRouteSegment segment : correctSegments) {
-				if (wrongSegment.getFirstWay().getId() == segment.getFirstWay().getId()
-						&& wrongSegment.getLastWay().getId() == segment.getLastWay().getId()) {
-					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 code:
-			if (numberOfFixes == 0) {
-				error.setMessage(tr("PT: Problem in the route segment with no automatic fix"));
-			} else if (numberOfFixes == 1) {
-				error.setMessage(tr("PT: Problem in the route segment with one automatic fix"));
-			} else {
-				error.setMessage("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
-	 */
-	private void findFix(TestError testError) {
-
-		PTRouteSegment wrongSegment = wrongSegments.get(testError);
-		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
-	 * @param currentFix
-	 * @param previousNode
-	 * @param endWay
-	 * @return
-	 */
-	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
-	 * @return
-	 */
-	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().getId() == segment.getFirstWay().getId()
-					&& wrongSegment.getLastWay().getId() == segment.getLastWay().getId()) {
-				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
-	 * @param testError
-	 */
-	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 (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);
-				}
-			});
-		}
-
-		// display the fix variants:
-		final PTAssistantValidatorTest test = (PTAssistantValidatorTest) testError.getTester();
-		test.addFixVariants(fixVariants);
-		PTAssistantLayer.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
-	 * @param fix
-	 */
-	private static Command carryOutSingleFix(TestError testError, List<PTWay> fix) {
-		// 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) {
-				// TODO Auto-generated catch block
-				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 testing)
-	 */
-	protected static void reset() {
-		correctSegments.clear();
-		wrongSegments.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 */
+    private static HashMap<TestError, PTRouteSegment> wrongSegments = 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());
+            TestError e = new TestError(this.test, Severity.WARNING, tr("PT: Relation member roles do not match tags"),
+                    PTAssistantValidatorTest.ERROR_CODE_RELAITON_MEMBER_ROLES, primitives, highlighted);
+            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());
+                TestError e = new TestError(this.test, Severity.WARNING,
+                        tr("PT: Route should start and end with a stop_position"),
+                        PTAssistantValidatorTest.ERROR_CODE_END_STOP, primitives, highlighted);
+                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);
+
+                TestError e = new TestError(this.test, Severity.WARNING, tr("PT: First or last way needs to be split"),
+                        PTAssistantValidatorTest.ERROR_CODE_SPLIT_WAY, primitives, highlighted);
+                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());
+                TestError e = new TestError(this.test, Severity.WARNING, tr("PT: First or last way needs to be split"),
+                        PTAssistantValidatorTest.ERROR_CODE_SPLIT_WAY, primitives, highlighted);
+                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;
+        }
+
+        // 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 (!this.errors.isEmpty() && this.errors.get(this.errors.size() - 1).getHighlighted().size() == 1
+                        && this.errors.get(this.errors.size() - 1).getHighlighted().iterator().next() == 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);
+                    TestError e = new TestError(this.test, Severity.WARNING, tr("PT: Problem in the route segment"),
+                            PTAssistantValidatorTest.ERROR_CODE_STOP_BY_STOP, primitives, highlighted);
+                    this.errors.add(e);
+                    PTRouteSegment routeSegment = new PTRouteSegment(startStop, endStop, segmentWays, relation);
+                    wrongSegments.put(e, routeSegment);
+                }
+                continue;
+            }
+
+            boolean sortingCorrect = existingWaySortingIsCorrect(segmentWays.get(0), firstNode,
+                    segmentWays.get(segmentWays.size() - 1));
+            if (sortingCorrect) {
+                PTRouteSegment routeSegment = new PTRouteSegment(startStop, endStop, segmentWays, relation);
+                addCorrectSegment(routeSegment);
+            } else {
+                PTRouteSegment routeSegment = new PTRouteSegment(startStop, endStop, segmentWays, relation);
+                TestError error = this.errors.get(this.errors.size() - 1);
+                wrongSegments.put(error, 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);
+        TestError e = new TestError(this.test, Severity.WARNING, tr("PT: Stop not served"),
+                PTAssistantValidatorTest.ERROR_CODE_STOP_NOT_SERVED, primitives, highlighted);
+        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 true if the sorting is correct, false otherwise.
+     */
+    private boolean existingWaySortingIsCorrect(PTWay start, Node startWayPreviousNodeInDirectionOfTravel, PTWay end) {
+
+        if (start == end) {
+            // if both PTStops are on the same PTWay
+            return true;
+        }
+
+        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) {
+                    List<Relation> primitives = new ArrayList<>(1);
+                    primitives.add(relation);
+                    List<OsmPrimitive> highlighted = new ArrayList<>();
+                    highlighted.addAll(current.getWays());
+                    TestError e = new TestError(this.test, Severity.WARNING, tr("PT: Problem in the route segment"),
+                            PTAssistantValidatorTest.ERROR_CODE_STOP_BY_STOP, primitives, highlighted);
+                    this.errors.add(e);
+                    return false;
+                }
+            } 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)) {
+                    List<Relation> primitives = new ArrayList<>(1);
+                    primitives.add(relation);
+                    List<OsmPrimitive> highlighted = new ArrayList<>();
+
+                    highlighted.addAll(current.getWays());
+
+                    TestError e = new TestError(this.test, Severity.WARNING, tr("PT: Problem in the route segment"),
+                            PTAssistantValidatorTest.ERROR_CODE_STOP_BY_STOP, primitives, highlighted);
+                    this.errors.add(e);
+                    return false;
+
+                }
+            }
+
+            current = nextPTWayAccortingToExistingSorting;
+
+        }
+
+        return true;
+    }
+
+    /**
+     * 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. Modifies the messages in the test
+     * error according to the availability of automatic fixes.
+     */
+    protected void findFixes() {
+
+        for (TestError error : wrongSegments.keySet()) {
+            // look for fixes using sorting and removing:
+            findFix(error);
+
+            // change the error code based on the availability of fixes:
+            PTRouteSegment wrongSegment = wrongSegments.get(error);
+            List<PTRouteSegment> correctSegmentsForThisError = new ArrayList<>();
+            for (PTRouteSegment segment : correctSegments) {
+                if (wrongSegment.getFirstWay().getId() == segment.getFirstWay().getId()
+                        && wrongSegment.getLastWay().getId() == segment.getLastWay().getId()) {
+                    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 code:
+            if (numberOfFixes == 0) {
+                error.setMessage(tr("PT: Problem in the route segment with no automatic fix"));
+            } else if (numberOfFixes == 1) {
+                error.setMessage(tr("PT: Problem in the route segment with one automatic fix"));
+            } else {
+                error.setMessage("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(TestError testError) {
+
+        PTRouteSegment wrongSegment = wrongSegments.get(testError);
+        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().getId() == segment.getFirstWay().getId()
+                    && wrongSegment.getLastWay().getId() == segment.getLastWay().getId()) {
+                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 (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);
+                }
+            });
+        }
+
+        // display the fix variants:
+        final PTAssistantValidatorTest test = (PTAssistantValidatorTest) testError.getTester();
+        test.addFixVariants(fixVariants);
+        PTAssistantLayer.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) {
+        // 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) {
+                // TODO Auto-generated catch block
+                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 testing)
+     */
+    protected static void reset() {
+        correctSegments.clear();
+        wrongSegments.clear();
+    }
 
 }
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/StopChecker.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/StopChecker.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/StopChecker.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.validation;
 
@@ -17,5 +18,5 @@
 /**
  * Performs tests of the stop area relations
- * 
+ *
  * @author
  *
@@ -23,110 +24,106 @@
 public class StopChecker extends Checker {
 
-	Set<OsmPrimitive> members;
+    Set<OsmPrimitive> members;
 
-	protected StopChecker(Relation relation, Test test) {
-		super(relation, test);
+    protected StopChecker(Relation relation, Test test) {
+        super(relation, test);
 
-		this.members = relation.getMemberPrimitives();
-	}
+        this.members = relation.getMemberPrimitives();
+    }
 
-	/**
-	 * Checks if the given stop area relation has a stop position.
-	 */
-	protected void performStopAreaStopPositionTest() {
+    /**
+     * Checks if the given stop area relation has a stop position.
+     */
+    protected void performStopAreaStopPositionTest() {
 
-		// No errors if there is a member tagged as stop position.
-		for (OsmPrimitive member : members) {
-			if (StopUtils.verifyStopAreaStopPosition(member)) {
-				return;
-			}
-		}
+        // No errors if there is a member tagged as stop position.
+        for (OsmPrimitive member : members) {
+            if (StopUtils.verifyStopAreaStopPosition(member)) {
+                return;
+            }
+        }
 
-		// Throw error message
-		List<OsmPrimitive> primitives = new ArrayList<>(1);
-		primitives.add(relation);
-		TestError e = new TestError(this.test, Severity.WARNING, tr("PT: Stop area relation has no stop position"),
-				PTAssistantValidatorTest.ERROR_CODE_STOP_AREA_NO_STOPS, primitives);
-		errors.add(e);
-	}
+        // Throw error message
+        List<OsmPrimitive> primitives = new ArrayList<>(1);
+        primitives.add(relation);
+        TestError e = new TestError(this.test, Severity.WARNING, tr("PT: Stop area relation has no stop position"),
+                PTAssistantValidatorTest.ERROR_CODE_STOP_AREA_NO_STOPS, primitives);
+        errors.add(e);
+    }
 
-	/**
-	 * Checks if the given stop area relation has a platform.
-	 */
-	protected void performStopAreaPlatformTest() {
+    /**
+     * Checks if the given stop area relation has a platform.
+     */
+    protected void performStopAreaPlatformTest() {
 
-		// No errors if there is a member tagged as platform.
-		for (OsmPrimitive member : members) {
-			if (StopUtils.verifyStopAreaPlatform(member)) {
-				return;
-			}
-		}
+        // No errors if there is a member tagged as platform.
+        for (OsmPrimitive member : members) {
+            if (StopUtils.verifyStopAreaPlatform(member)) {
+                return;
+            }
+        }
 
-		// Throw error message
-		List<OsmPrimitive> primitives = new ArrayList<>(1);
-		primitives.add(relation);
-		TestError e = new TestError(this.test, Severity.WARNING, tr("PT: Stop area relation has no platform"),
-				PTAssistantValidatorTest.ERROR_CODE_STOP_AREA_NO_PLATFORM, primitives);
-		errors.add(e);
+        // Throw error message
+        List<OsmPrimitive> primitives = new ArrayList<>(1);
+        primitives.add(relation);
+        TestError e = new TestError(this.test, Severity.WARNING, tr("PT: Stop area relation has no platform"),
+                PTAssistantValidatorTest.ERROR_CODE_STOP_AREA_NO_PLATFORM, primitives);
+        errors.add(e);
 
-	}
+    }
 
-	/**
-	 * Checks if the stop_position(s) of an stop area belong to the same route
-	 * relations as its related platform(s).
-	 * 
-	 * @param n
-	 */
-	protected void performStopAreaRelationsTest() {
+    /**
+     * Checks if the stop_position(s) of an stop area belong to the same route
+     * relations as its related platform(s).
+     */
+    protected void performStopAreaRelationsTest() {
 
-		HashMap<Long, Long> stopPositionRelationIds = new HashMap<>();
-		HashMap<Long, Long> platformRelationIds = new HashMap<>();
+        HashMap<Long, Long> stopPositionRelationIds = new HashMap<>();
+        HashMap<Long, Long> platformRelationIds = new HashMap<>();
 
-		// Loop through all members
-		for (OsmPrimitive member : members) {
+        // Loop through all members
+        for (OsmPrimitive member : members) {
 
-			// For stop positions...
-			if (StopUtils.verifyStopAreaStopPosition(member)) {
+            // For stop positions...
+            if (StopUtils.verifyStopAreaStopPosition(member)) {
 
-				// Create a list of assigned route relations
-				for (Relation referrer : OsmPrimitive.getFilteredList(member.getReferrers(), Relation.class)) {
-					if (referrer.get("type") == "route") {
-						stopPositionRelationIds.put(referrer.getId(), referrer.getId());
-					}
-				}
-			}
+                // Create a list of assigned route relations
+                for (Relation referrer : OsmPrimitive.getFilteredList(member.getReferrers(), Relation.class)) {
+                    if (referrer.get("type") == "route") {
+                        stopPositionRelationIds.put(referrer.getId(), referrer.getId());
+                    }
+                }
+            // For platforms...
+            } else if (StopUtils.verifyStopAreaPlatform(member)) {
 
-			// For platforms...
-			else if (StopUtils.verifyStopAreaPlatform(member)) {
+                // Create a list of assigned route relations
+                for (Relation referrer : OsmPrimitive.getFilteredList(member.getReferrers(), Relation.class)) {
+                    if (referrer.get("type") == "route") {
+                        platformRelationIds.put(referrer.getId(), referrer.getId());
+                    }
+                }
+            }
+        }
 
-				// Create a list of assigned route relations
-				for (Relation referrer : OsmPrimitive.getFilteredList(member.getReferrers(), Relation.class)) {
-					if (referrer.get("type") == "route") {
-						platformRelationIds.put(referrer.getId(), referrer.getId());
-					}
-				}
-			}
-		}
+        // Check if the stop_position has no referrers at all. If it has no
+        // referrers, then no error should be reported (changed on 11.08.2016 by
+        // darya):
+        if (stopPositionRelationIds.isEmpty()) {
+            return;
+        }
 
-		// Check if the stop_position has no referrers at all. If it has no
-		// referrers, then no error should be reported (changed on 11.08.2016 by
-		// darya):
-		if (stopPositionRelationIds.isEmpty()) {
-			return;
-		}
+        // Check if route relation lists are identical
+        if (stopPositionRelationIds.equals(platformRelationIds)) {
+            return;
+        }
 
-		// Check if route relation lists are identical
-		if (stopPositionRelationIds.equals(platformRelationIds)) {
-			return;
-		}
-
-		// Throw error message
-		List<OsmPrimitive> primitives = new ArrayList<>(1);
-		primitives.add(relation);
-		TestError e = new TestError(this.test, Severity.WARNING,
-				tr("PT: Route relations of stop position(s) and platform(s) of stop area members diverge"),
-				PTAssistantValidatorTest.ERROR_CODE_STOP_AREA_COMPARE_RELATIONS, primitives);
-		errors.add(e);
-	}
+        // Throw error message
+        List<OsmPrimitive> primitives = new ArrayList<>(1);
+        primitives.add(relation);
+        TestError e = new TestError(this.test, Severity.WARNING,
+                tr("PT: Route relations of stop position(s) and platform(s) of stop area members diverge"),
+                PTAssistantValidatorTest.ERROR_CODE_STOP_AREA_COMPARE_RELATIONS, primitives);
+        errors.add(e);
+    }
 
 }
Index: /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/WayChecker.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/WayChecker.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/WayChecker.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.validation;
 
@@ -25,5 +26,5 @@
  * Performs tests of a route at the level of single ways: DirectionTest and
  * RoadTypeTest
- * 
+ *
  * @author darya
  *
@@ -31,414 +32,415 @@
 public class WayChecker extends Checker {
 
-	public WayChecker(Relation relation, Test test) {
-
-		super(relation, test);
-
-	}
-
-	protected void performRoadTypeTest() {
-
-		if (!relation.hasTag("route", "bus") && !relation.hasTag("route", "trolleybus")
-				&& !relation.hasTag("route", "share_taxi")) {
-			return;
-		}
-
-		for (RelationMember rm : relation.getMembers()) {
-			if (RouteUtils.isPTWay(rm) && rm.getType().equals(OsmPrimitiveType.WAY)) {
-
-				Way way = rm.getWay();
-				// at this point, the relation has already been checked to
-				// be a route of public_transport:version 2
-
-				boolean isCorrectRoadType = true;
-				boolean isUnderConstruction = false;
-				if (way.hasKey("construction")) {
-					isUnderConstruction = true;
-				}
-				if (relation.hasTag("route", "bus") || relation.hasTag("route", "share_taxi")) {
-					if (!RouteUtils.isWaySuitableForBuses(way)) {
-						isCorrectRoadType = false;
-					}
-					if (way.hasTag("highway", "construction")) {
-						isUnderConstruction = true;
-					}
-				} else if (relation.hasTag("route", "trolleybus")) {
-					if (!(RouteUtils.isWaySuitableForBuses(way) && way.hasTag("trolley_wire", "yes"))) {
-						isCorrectRoadType = false;
-					}
-					if (way.hasTag("highway", "construction")) {
-						isUnderConstruction = true;
-					}
-				} else if (relation.hasTag("route", "tram")) {
-					if (!way.hasTag("railway", "tram")) {
-						isCorrectRoadType = false;
-					}
-					if (way.hasTag("railway", "construction")) {
-						isUnderConstruction = true;
-					}
-				} else if (relation.hasTag("route", "subway")) {
-					if (!way.hasTag("railway", "subway")) {
-						isCorrectRoadType = false;
-					}
-					if (way.hasTag("railway", "construction")) {
-						isUnderConstruction = true;
-					}
-				} else if (relation.hasTag("route", "light_rail")) {
-					if (!way.hasTag("railway", "subway")) {
-						isCorrectRoadType = false;
-					}
-					if (way.hasTag("railway", "construction")) {
-						isUnderConstruction = true;
-					}
-				} else if (relation.hasTag("route", "light_rail")) {
-					if (!way.hasTag("railway", "light_rail")) {
-						isCorrectRoadType = false;
-					}
-					if (way.hasTag("railway", "construction")) {
-						isUnderConstruction = true;
-					}
-				} else if (relation.hasTag("route", "train")) {
-					if (!way.hasTag("railway", "rail")) {
-						isCorrectRoadType = false;
-					}
-					if (way.hasTag("railway", "construction")) {
-						isUnderConstruction = true;
-					}
-				}
-
-				if (!isCorrectRoadType && !isUnderConstruction) {
-
-					List<Relation> primitives = new ArrayList<>(1);
-					primitives.add(relation);
-					List<Way> highlighted = new ArrayList<>(1);
-					highlighted.add(way);
-					TestError e = new TestError(this.test, Severity.WARNING,
-							tr("PT: Route type does not match the type of the road it passes on"),
-							PTAssistantValidatorTest.ERROR_CODE_ROAD_TYPE, primitives, highlighted);
-					errors.add(e);
-
-				}
-
-				if (isUnderConstruction) {
-					List<Relation> primitives = new ArrayList<>(1);
-					primitives.add(relation);
-					List<Way> highlighted = new ArrayList<>(1);
-					highlighted.add(way);
-					TestError e = new TestError(this.test, Severity.WARNING, tr("PT: Road is under construction"),
-							PTAssistantValidatorTest.ERROR_CODE_CONSTRUCTION, primitives, highlighted);
-					errors.add(e);
-				}
-			}
-		}
-
-	}
-
-	protected void performDirectionTest() {
-
-		List<Way> waysToCheck = new ArrayList<>();
-
-		for (RelationMember rm : relation.getMembers()) {
-			if (RouteUtils.isPTWay(rm)) {
-				if (rm.isWay()) {
-					waysToCheck.add(rm.getWay());
-				} else {
-					Relation nestedRelation = rm.getRelation();
-					for (RelationMember nestedRelationMember : nestedRelation.getMembers()) {
-						waysToCheck.add(nestedRelationMember.getWay());
-					}
-				}
-			}
-		}
-
-		if (waysToCheck.size() <= 1) {
-			return;
-		}
-
-		List<Way> problematicWays = new ArrayList<>();
-
-		for (int i = 0; i < waysToCheck.size(); i++) {
-
-			Way curr = waysToCheck.get(i);
-
-			if (i == 0) {
-				// first way:
-				Way next = waysToCheck.get(i + 1);
-				if (!touchCorrectly(null, curr, next)) {
-					problematicWays.add(curr);
-				}
-
-			} else if (i == waysToCheck.size() - 1) {
-				// last way:
-				Way prev = waysToCheck.get(i - 1);
-				if (!touchCorrectly(prev, curr, null)) {
-					problematicWays.add(curr);
-				}
-
-			} else {
-				// all other ways:
-				Way prev = waysToCheck.get(i - 1);
-				Way next = waysToCheck.get(i + 1);
-				if (!touchCorrectly(prev, curr, next)) {
-					problematicWays.add(curr);
-				}
-			}
-		}
-
-		List<Relation> primitives = new ArrayList<>(1);
-		primitives.add(this.relation);
-
-		List<Set<Way>> listOfSets = new ArrayList<>();
-		for (Way problematicWay : problematicWays) {
-			Set<Way> primitivesToReport = new HashSet<>();
-			primitivesToReport.add(problematicWay);
-			primitivesToReport.addAll(checkAdjacentWays(problematicWay, new HashSet<Way>()));
-			listOfSets.add(primitivesToReport);
-		}
-		
-		boolean changed = true;
-		while (changed) {
-			changed = false;
-			for (int i = 0; i < listOfSets.size(); i++) {
-				for (int j = i; j < listOfSets.size(); j++) {
-					if (i != j && RouteUtils.waysTouch(listOfSets.get(i), listOfSets.get(j))) {
-						listOfSets.get(i).addAll(listOfSets.get(j));
-						listOfSets.remove(j);
-						j = listOfSets.size();
-						changed = true;
-					}
-				}
-			}
-		}
-
-		for (Set<Way> currentSet : listOfSets) {
-			TestError e = new TestError(this.test, Severity.WARNING,
-					tr("PT: Route passes a oneway road in the wrong direction"),
-					PTAssistantValidatorTest.ERROR_CODE_DIRECTION, primitives, currentSet);
-			this.errors.add(e);
-		}
-
-	}
-
-	/**
-	 * Checks if the current way touches its neighboring ways correctly
-	 * 
-	 * @param prev
-	 *            can be null
-	 * @param curr
-	 *            cannot be null
-	 * @param next
-	 *            can be null
-	 * @return
-	 */
-	private boolean touchCorrectly(Way prev, Way curr, Way next) {
-
-		if (RouteUtils.isOnewayForPublicTransport(curr) == 0) {
-			return true;
-		}
-
-		if (prev != null) {
-
-			if (RouteUtils.waysTouch(curr, prev)) {
-				Node nodeInQuestion;
-				if (RouteUtils.isOnewayForPublicTransport(curr) == 1) {
-					nodeInQuestion = curr.firstNode();
-				} else {
-					nodeInQuestion = curr.lastNode();
-				}
-
-				List<Way> nb = findNeighborWays(curr, nodeInQuestion);
-
-				if (nb.size() < 2 && nodeInQuestion != prev.firstNode() && nodeInQuestion != prev.lastNode()) {
-					return false;
-				}
-			}
-		}
-
-		if (next != null) {
-
-			if (RouteUtils.waysTouch(curr, next)) {
-				Node nodeInQuestion;
-				if (RouteUtils.isOnewayForPublicTransport(curr) == 1) {
-					nodeInQuestion = curr.lastNode();
-				} else {
-					nodeInQuestion = curr.firstNode();
-				}
-
-				List<Way> nb = findNeighborWays(curr, nodeInQuestion);
-
-				if (nb.size() < 2 && nodeInQuestion != next.firstNode() && nodeInQuestion != next.lastNode()) {
-					return false;
-				}
-			}
-		}
-
-		return true;
-
-	}
-
-	protected Set<Way> checkAdjacentWays(Way curr, Set<Way> flags) {
-		// curr is supposed to be a wrong oneway way!!
-
-		Set<Way> resultSet = new HashSet<>();
-		resultSet.addAll(flags);
-		resultSet.add(curr);
-
-		if (RouteUtils.isOnewayForPublicTransport(curr) == 0) {
-			return null;
-		}
-
-		Node firstNodeInRouteDirection;
-		Node lastNodeInRouteDirection;
-		if (RouteUtils.isOnewayForPublicTransport(curr) == 1) {
-			firstNodeInRouteDirection = curr.lastNode();
-			lastNodeInRouteDirection = curr.firstNode();
-		} else {
-			firstNodeInRouteDirection = curr.firstNode();
-			lastNodeInRouteDirection = curr.lastNode();
-		}
-
-		List<Way> firstNodeInRouteDirectionNeighbors = findNeighborWays(curr, firstNodeInRouteDirection);
-		List<Way> lastNodeInRouteDirectionNeighbors = findNeighborWays(curr, lastNodeInRouteDirection);
-
-		for (Way nb : firstNodeInRouteDirectionNeighbors) {
-
-			if (resultSet.contains(nb)) {
-				continue;
-			}
-
-			if (RouteUtils.isOnewayForPublicTransport(nb) == 1 && nb.firstNode() == firstNodeInRouteDirection) {
-				Set<Way> newSet = this.checkAdjacentWays(nb, resultSet);
-				resultSet.addAll(newSet);
-
-			} else if (RouteUtils.isOnewayForPublicTransport(nb) == -1 && nb.lastNode() == firstNodeInRouteDirection) {
-				Set<Way> newSet = this.checkAdjacentWays(nb, resultSet);
-				resultSet.addAll(newSet);
-
-			}
-		}
-
-		for (Way nb : lastNodeInRouteDirectionNeighbors) {
-
-			if (resultSet.contains(nb)) {
-				continue;
-			}
-
-			if (RouteUtils.isOnewayForPublicTransport(nb) == 1 && nb.lastNode() == lastNodeInRouteDirection) {
-				Set<Way> newSet = this.checkAdjacentWays(nb, resultSet);
-				resultSet.addAll(newSet);
-			} else if (RouteUtils.isOnewayForPublicTransport(nb) == -1 && nb.firstNode() == lastNodeInRouteDirection) {
-				Set<Way> newSet = this.checkAdjacentWays(nb, resultSet);
-				resultSet.addAll(newSet);
-			}
-
-		}
-
-		return resultSet;
-
-	}
-
-	/**
-	 * Finds all ways that touch the given way at the given node AND belong to
-	 * the relation of this WayChecker
-	 * 
-	 * @param way
-	 * @param node
-	 * @return
-	 */
-	private List<Way> findNeighborWays(Way way, Node node) {
-
-		List<Way> resultList = new ArrayList<>();
-
-		List<OsmPrimitive> nodeReferrers = node.getReferrers();
-
-		for (OsmPrimitive referrer : nodeReferrers) {
-			if (referrer.getType().equals(OsmPrimitiveType.WAY)) {
-				Way neighborWay = (Way) referrer;
-				if (neighborWay != way && containsWay(neighborWay)) {
-					resultList.add(neighborWay);
-				}
-			}
-		}
-
-		return resultList;
-	}
-
-	/**
-	 * Checks if the relation of this WayChecker contains the given way
-	 * 
-	 * @param way
-	 * @return
-	 */
-	private boolean containsWay(Way way) {
-
-		List<RelationMember> members = relation.getMembers();
-
-		for (RelationMember rm : members) {
-			if (rm.isWay() && rm.getWay() == way) {
-				return true;
-			}
-		}
-
-		return false;
-
-	}
-
-	protected static Command fixErrorByRemovingWay(TestError testError) {
-
-		if (testError.getCode() != PTAssistantValidatorTest.ERROR_CODE_ROAD_TYPE
-				&& testError.getCode() != PTAssistantValidatorTest.ERROR_CODE_DIRECTION) {
-			return null;
-		}
-
-		Collection<? extends OsmPrimitive> primitives = testError.getPrimitives();
-		Relation originalRelation = (Relation) primitives.iterator().next();
-		Collection<?> highlighted = testError.getHighlighted();
-		Way wayToRemove = (Way) highlighted.iterator().next();
-
-		Relation modifiedRelation = new Relation(originalRelation);
-		List<RelationMember> modifiedRelationMembers = new ArrayList<>(originalRelation.getMembersCount() - 1);
-
-		// copy PT stops first, PT ways last:
-		for (RelationMember rm : originalRelation.getMembers()) {
-			if (RouteUtils.isPTStop(rm)) {
-
-				if (rm.getRole().equals("stop_position")) {
-					if (rm.getType().equals(OsmPrimitiveType.NODE)) {
-						RelationMember newMember = new RelationMember("stop", rm.getNode());
-						modifiedRelationMembers.add(newMember);
-					} else { // if it is a way:
-						RelationMember newMember = new RelationMember("stop", rm.getWay());
-						modifiedRelationMembers.add(newMember);
-					}
-				} else {
-					// if the relation member does not have the role
-					// "stop_position":
-					modifiedRelationMembers.add(rm);
-				}
-
-			}
-		}
-
-		// now copy PT ways:
-		for (RelationMember rm : originalRelation.getMembers()) {
-			if (RouteUtils.isPTWay(rm)) {
-				Way wayToCheck = rm.getWay();
-				if (wayToCheck != wayToRemove) {
-					if (rm.getRole().equals("forward") || rm.getRole().equals("backward")) {
-						RelationMember modifiedMember = new RelationMember("", wayToCheck);
-						modifiedRelationMembers.add(modifiedMember);
-					} else {
-						modifiedRelationMembers.add(rm);
-					}
-				}
-			}
-		}
-
-		modifiedRelation.setMembers(modifiedRelationMembers);
-
-		ChangeCommand changeCommand = new ChangeCommand(originalRelation, modifiedRelation);
-
-		return changeCommand;
-	}
+    public WayChecker(Relation relation, Test test) {
+
+        super(relation, test);
+
+    }
+
+    protected void performRoadTypeTest() {
+
+        if (!relation.hasTag("route", "bus") && !relation.hasTag("route", "trolleybus")
+                && !relation.hasTag("route", "share_taxi")) {
+            return;
+        }
+
+        for (RelationMember rm : relation.getMembers()) {
+            if (RouteUtils.isPTWay(rm) && rm.getType().equals(OsmPrimitiveType.WAY)) {
+
+                Way way = rm.getWay();
+                // at this point, the relation has already been checked to
+                // be a route of public_transport:version 2
+
+                boolean isCorrectRoadType = true;
+                boolean isUnderConstruction = false;
+                if (way.hasKey("construction")) {
+                    isUnderConstruction = true;
+                }
+                if (relation.hasTag("route", "bus") || relation.hasTag("route", "share_taxi")) {
+                    if (!RouteUtils.isWaySuitableForBuses(way)) {
+                        isCorrectRoadType = false;
+                    }
+                    if (way.hasTag("highway", "construction")) {
+                        isUnderConstruction = true;
+                    }
+                } else if (relation.hasTag("route", "trolleybus")) {
+                    if (!(RouteUtils.isWaySuitableForBuses(way) && way.hasTag("trolley_wire", "yes"))) {
+                        isCorrectRoadType = false;
+                    }
+                    if (way.hasTag("highway", "construction")) {
+                        isUnderConstruction = true;
+                    }
+                } else if (relation.hasTag("route", "tram")) {
+                    if (!way.hasTag("railway", "tram")) {
+                        isCorrectRoadType = false;
+                    }
+                    if (way.hasTag("railway", "construction")) {
+                        isUnderConstruction = true;
+                    }
+                } else if (relation.hasTag("route", "subway")) {
+                    if (!way.hasTag("railway", "subway")) {
+                        isCorrectRoadType = false;
+                    }
+                    if (way.hasTag("railway", "construction")) {
+                        isUnderConstruction = true;
+                    }
+                } else if (relation.hasTag("route", "light_rail")) {
+                    if (!way.hasTag("railway", "subway")) {
+                        isCorrectRoadType = false;
+                    }
+                    if (way.hasTag("railway", "construction")) {
+                        isUnderConstruction = true;
+                    }
+                } else if (relation.hasTag("route", "light_rail")) {
+                    if (!way.hasTag("railway", "light_rail")) {
+                        isCorrectRoadType = false;
+                    }
+                    if (way.hasTag("railway", "construction")) {
+                        isUnderConstruction = true;
+                    }
+                } else if (relation.hasTag("route", "train")) {
+                    if (!way.hasTag("railway", "rail")) {
+                        isCorrectRoadType = false;
+                    }
+                    if (way.hasTag("railway", "construction")) {
+                        isUnderConstruction = true;
+                    }
+                }
+
+                if (!isCorrectRoadType && !isUnderConstruction) {
+
+                    List<Relation> primitives = new ArrayList<>(1);
+                    primitives.add(relation);
+                    List<Way> highlighted = new ArrayList<>(1);
+                    highlighted.add(way);
+                    TestError e = new TestError(this.test, Severity.WARNING,
+                            tr("PT: Route type does not match the type of the road it passes on"),
+                            PTAssistantValidatorTest.ERROR_CODE_ROAD_TYPE, primitives, highlighted);
+                    errors.add(e);
+
+                }
+
+                if (isUnderConstruction) {
+                    List<Relation> primitives = new ArrayList<>(1);
+                    primitives.add(relation);
+                    List<Way> highlighted = new ArrayList<>(1);
+                    highlighted.add(way);
+                    TestError e = new TestError(this.test, Severity.WARNING, tr("PT: Road is under construction"),
+                            PTAssistantValidatorTest.ERROR_CODE_CONSTRUCTION, primitives, highlighted);
+                    errors.add(e);
+                }
+            }
+        }
+
+    }
+
+    protected void performDirectionTest() {
+
+        List<Way> waysToCheck = new ArrayList<>();
+
+        for (RelationMember rm : relation.getMembers()) {
+            if (RouteUtils.isPTWay(rm)) {
+                if (rm.isWay()) {
+                    waysToCheck.add(rm.getWay());
+                } else {
+                    Relation nestedRelation = rm.getRelation();
+                    for (RelationMember nestedRelationMember : nestedRelation.getMembers()) {
+                        waysToCheck.add(nestedRelationMember.getWay());
+                    }
+                }
+            }
+        }
+
+        if (waysToCheck.size() <= 1) {
+            return;
+        }
+
+        List<Way> problematicWays = new ArrayList<>();
+
+        for (int i = 0; i < waysToCheck.size(); i++) {
+
+            Way curr = waysToCheck.get(i);
+
+            if (i == 0) {
+                // first way:
+                Way next = waysToCheck.get(i + 1);
+                if (!touchCorrectly(null, curr, next)) {
+                    problematicWays.add(curr);
+                }
+
+            } else if (i == waysToCheck.size() - 1) {
+                // last way:
+                Way prev = waysToCheck.get(i - 1);
+                if (!touchCorrectly(prev, curr, null)) {
+                    problematicWays.add(curr);
+                }
+
+            } else {
+                // all other ways:
+                Way prev = waysToCheck.get(i - 1);
+                Way next = waysToCheck.get(i + 1);
+                if (!touchCorrectly(prev, curr, next)) {
+                    problematicWays.add(curr);
+                }
+            }
+        }
+
+        List<Relation> primitives = new ArrayList<>(1);
+        primitives.add(this.relation);
+
+        List<Set<Way>> listOfSets = new ArrayList<>();
+        for (Way problematicWay : problematicWays) {
+            Set<Way> primitivesToReport = new HashSet<>();
+            primitivesToReport.add(problematicWay);
+            primitivesToReport.addAll(checkAdjacentWays(problematicWay, new HashSet<Way>()));
+            listOfSets.add(primitivesToReport);
+        }
+
+        boolean changed = true;
+        while (changed) {
+            changed = false;
+            for (int i = 0; i < listOfSets.size(); i++) {
+                for (int j = i; j < listOfSets.size(); j++) {
+                    if (i != j && RouteUtils.waysTouch(listOfSets.get(i), listOfSets.get(j))) {
+                        listOfSets.get(i).addAll(listOfSets.get(j));
+                        listOfSets.remove(j);
+                        j = listOfSets.size();
+                        changed = true;
+                    }
+                }
+            }
+        }
+
+        for (Set<Way> currentSet : listOfSets) {
+            TestError e = new TestError(this.test, Severity.WARNING,
+                    tr("PT: Route passes a oneway road in the wrong direction"),
+                    PTAssistantValidatorTest.ERROR_CODE_DIRECTION, primitives, currentSet);
+            this.errors.add(e);
+        }
+
+    }
+
+    /**
+     * Checks if the current way touches its neighboring ways correctly
+     *
+     * @param prev
+     *            can be null
+     * @param curr
+     *            cannot be null
+     * @param next
+     *            can be null
+     * @return {@code true} if the current way touches its neighboring ways correctly
+     */
+    private boolean touchCorrectly(Way prev, Way curr, Way next) {
+
+        if (RouteUtils.isOnewayForPublicTransport(curr) == 0) {
+            return true;
+        }
+
+        if (prev != null) {
+
+            if (RouteUtils.waysTouch(curr, prev)) {
+                Node nodeInQuestion;
+                if (RouteUtils.isOnewayForPublicTransport(curr) == 1) {
+                    nodeInQuestion = curr.firstNode();
+                } else {
+                    nodeInQuestion = curr.lastNode();
+                }
+
+                List<Way> nb = findNeighborWays(curr, nodeInQuestion);
+
+                if (nb.size() < 2 && nodeInQuestion != prev.firstNode() && nodeInQuestion != prev.lastNode()) {
+                    return false;
+                }
+            }
+        }
+
+        if (next != null) {
+
+            if (RouteUtils.waysTouch(curr, next)) {
+                Node nodeInQuestion;
+                if (RouteUtils.isOnewayForPublicTransport(curr) == 1) {
+                    nodeInQuestion = curr.lastNode();
+                } else {
+                    nodeInQuestion = curr.firstNode();
+                }
+
+                List<Way> nb = findNeighborWays(curr, nodeInQuestion);
+
+                if (nb.size() < 2 && nodeInQuestion != next.firstNode() && nodeInQuestion != next.lastNode()) {
+                    return false;
+                }
+            }
+        }
+
+        return true;
+
+    }
+
+    protected Set<Way> checkAdjacentWays(Way curr, Set<Way> flags) {
+        // curr is supposed to be a wrong oneway way!!
+
+        Set<Way> resultSet = new HashSet<>();
+        resultSet.addAll(flags);
+        resultSet.add(curr);
+
+        if (RouteUtils.isOnewayForPublicTransport(curr) == 0) {
+            return null;
+        }
+
+        Node firstNodeInRouteDirection;
+        Node lastNodeInRouteDirection;
+        if (RouteUtils.isOnewayForPublicTransport(curr) == 1) {
+            firstNodeInRouteDirection = curr.lastNode();
+            lastNodeInRouteDirection = curr.firstNode();
+        } else {
+            firstNodeInRouteDirection = curr.firstNode();
+            lastNodeInRouteDirection = curr.lastNode();
+        }
+
+        List<Way> firstNodeInRouteDirectionNeighbors = findNeighborWays(curr, firstNodeInRouteDirection);
+        List<Way> lastNodeInRouteDirectionNeighbors = findNeighborWays(curr, lastNodeInRouteDirection);
+
+        for (Way nb : firstNodeInRouteDirectionNeighbors) {
+
+            if (resultSet.contains(nb)) {
+                continue;
+            }
+
+            if (RouteUtils.isOnewayForPublicTransport(nb) == 1 && nb.firstNode() == firstNodeInRouteDirection) {
+                Set<Way> newSet = this.checkAdjacentWays(nb, resultSet);
+                resultSet.addAll(newSet);
+
+            } else if (RouteUtils.isOnewayForPublicTransport(nb) == -1 && nb.lastNode() == firstNodeInRouteDirection) {
+                Set<Way> newSet = this.checkAdjacentWays(nb, resultSet);
+                resultSet.addAll(newSet);
+
+            }
+        }
+
+        for (Way nb : lastNodeInRouteDirectionNeighbors) {
+
+            if (resultSet.contains(nb)) {
+                continue;
+            }
+
+            if (RouteUtils.isOnewayForPublicTransport(nb) == 1 && nb.lastNode() == lastNodeInRouteDirection) {
+                Set<Way> newSet = this.checkAdjacentWays(nb, resultSet);
+                resultSet.addAll(newSet);
+            } else if (RouteUtils.isOnewayForPublicTransport(nb) == -1 && nb.firstNode() == lastNodeInRouteDirection) {
+                Set<Way> newSet = this.checkAdjacentWays(nb, resultSet);
+                resultSet.addAll(newSet);
+            }
+
+        }
+
+        return resultSet;
+
+    }
+
+    /**
+     * Finds all ways that touch the given way at the given node AND belong to
+     * the relation of this WayChecker
+     *
+     * @param way way
+     * @param node node
+     * @return all ways that touch the given way at the given node AND belong to
+     * the relation of this WayChecker
+     */
+    private List<Way> findNeighborWays(Way way, Node node) {
+
+        List<Way> resultList = new ArrayList<>();
+
+        List<OsmPrimitive> nodeReferrers = node.getReferrers();
+
+        for (OsmPrimitive referrer : nodeReferrers) {
+            if (referrer.getType().equals(OsmPrimitiveType.WAY)) {
+                Way neighborWay = (Way) referrer;
+                if (neighborWay != way && containsWay(neighborWay)) {
+                    resultList.add(neighborWay);
+                }
+            }
+        }
+
+        return resultList;
+    }
+
+    /**
+     * Checks if the relation of this WayChecker contains the given way
+     *
+     * @param way way
+     * @return {@code true} if the relation of this WayChecker contains the given way
+     */
+    private boolean containsWay(Way way) {
+
+        List<RelationMember> members = relation.getMembers();
+
+        for (RelationMember rm : members) {
+            if (rm.isWay() && rm.getWay() == way) {
+                return true;
+            }
+        }
+
+        return false;
+
+    }
+
+    protected static Command fixErrorByRemovingWay(TestError testError) {
+
+        if (testError.getCode() != PTAssistantValidatorTest.ERROR_CODE_ROAD_TYPE
+                && testError.getCode() != PTAssistantValidatorTest.ERROR_CODE_DIRECTION) {
+            return null;
+        }
+
+        Collection<? extends OsmPrimitive> primitives = testError.getPrimitives();
+        Relation originalRelation = (Relation) primitives.iterator().next();
+        Collection<?> highlighted = testError.getHighlighted();
+        Way wayToRemove = (Way) highlighted.iterator().next();
+
+        Relation modifiedRelation = new Relation(originalRelation);
+        List<RelationMember> modifiedRelationMembers = new ArrayList<>(originalRelation.getMembersCount() - 1);
+
+        // copy PT stops first, PT ways last:
+        for (RelationMember rm : originalRelation.getMembers()) {
+            if (RouteUtils.isPTStop(rm)) {
+
+                if (rm.getRole().equals("stop_position")) {
+                    if (rm.getType().equals(OsmPrimitiveType.NODE)) {
+                        RelationMember newMember = new RelationMember("stop", rm.getNode());
+                        modifiedRelationMembers.add(newMember);
+                    } else { // if it is a way:
+                        RelationMember newMember = new RelationMember("stop", rm.getWay());
+                        modifiedRelationMembers.add(newMember);
+                    }
+                } else {
+                    // if the relation member does not have the role
+                    // "stop_position":
+                    modifiedRelationMembers.add(rm);
+                }
+
+            }
+        }
+
+        // now copy PT ways:
+        for (RelationMember rm : originalRelation.getMembers()) {
+            if (RouteUtils.isPTWay(rm)) {
+                Way wayToCheck = rm.getWay();
+                if (wayToCheck != wayToRemove) {
+                    if (rm.getRole().equals("forward") || rm.getRole().equals("backward")) {
+                        RelationMember modifiedMember = new RelationMember("", wayToCheck);
+                        modifiedRelationMembers.add(modifiedMember);
+                    } else {
+                        modifiedRelationMembers.add(rm);
+                    }
+                }
+            }
+        }
+
+        modifiedRelation.setMembers(modifiedRelationMembers);
+
+        ChangeCommand changeCommand = new ChangeCommand(originalRelation, modifiedRelation);
+
+        return changeCommand;
+    }
 
 }
Index: /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/AbstractTest.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/AbstractTest.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/AbstractTest.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant;
 
@@ -13,36 +14,36 @@
 public abstract class AbstractTest {
 
- public static final String PATH_TO_DL131_BEFORE = "test/data/DL131_before.osm"; // 
+ public static final String PATH_TO_DL131_BEFORE = "test/data/DL131_before.osm"; //
  public static final String PATH_TO_DL131_AFTER = "test/data/DL131_after.osm";
- 
+
  public static final String PATH_TO_DL4_BEFORE = "test/data/DL4_before.osm";
  public static final String PATH_TO_DL4_AFTER = "test/data/DL4_after.osm";
- 
+
  public static final String PATH_TO_DL49_BEFORE = "test/data/DL49_before.osm"; // has wrong way sorting
  public static final String PATH_TO_DL49_AFTER = "test/data/DL49_after.osm";
- 
+
  public static final String PATH_TO_DL60_BEFORE = "test/data/DL60_before.osm";
  public static final String PATH_TO_DL60_AFTER = "test/data/DL60_after.osm";
- 
+
  public static final String PATH_TO_DL94_BEFORE = "test/data/DL94_before.osm";
  public static final String PATH_TO_DL94_AFTER = "test/data/DL94_after.osm";
- 
+
  public static final String PATH_TO_DL286_BEFORE = "test/data/DL286_before.osm";
  public static final String PATH_TO_DL286_AFTER = "test/data/DL286_after.osm";
- 
+
  public static final String PATH_TO_TEC366_BEFORE = "test/data/TL366_before.osm";
  public static final String PATH_TO_TEC366_AFTER = "test/data/TL366_after.osm";
- 
+
  public static final String PATH_TO_PLATFORM_AS_WAY = "test/data/route-with-platform-as-way.osm";
- 
+
  public static final String PATH_TO_ROUNDABOUT_ONEWAY = "test/data/duesseldorf_roundabout.osm";
- 
+
  public static final String PATH_TO_ROAD_TYPE_ERROR = "test/data/road-type.osm";
- 
+
  public static final String PATH_TO_ONEWAY_BAD_MEMBER_SORTING = "test/data/oneway-bad-member-sorting.osm";
- 
+
  public static final String PATH_TO_ONEWAY_WRONG_DIRECTION = "test/data/oneway-wrong-direction.osm";
  public static final String PATH_TO_ONEWAY_WRONG_DIRECTION2 = "test/data/oneway-wrong-direction2.osm";
- 
+
  public static final String PATH_TO_SOLITARY_STOP_POSITION = "test/data/solitary-stop-position.osm";
 
@@ -54,5 +55,5 @@
  public static final String PATH_TO_STOP_AREA_MANY_PLATFORMS = "test/data/stop-area-many-platforms.osm";
 
- 
+
  public static final String PATH_TO_SEGMENT_TEST = "test/data/segment-test.osm";
 
Index: /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/ImportUtils.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/ImportUtils.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/ImportUtils.java	(revision 33055)
@@ -1,7 +1,4 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant;
-
-/**
- * This class provides functionality used by multiple test classes of pt_assistant plugin. 
- */
 
 import java.io.File;
@@ -18,6 +15,9 @@
 import org.openstreetmap.josm.io.OsmImporter.OsmImporterData;
 
-public class ImportUtils {
-    
+/**
+ * This class provides functionality used by multiple test classes of pt_assistant plugin.
+ */
+public final class ImportUtils {
+
     private ImportUtils() {
         // private constructor for utils classes
@@ -42,10 +42,6 @@
             e.printStackTrace();
         }
-        
+
         return null;
-
     }
-
-
-
 }
Index: /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/TestUtil.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/TestUtil.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/TestUtil.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant;
 
@@ -34,5 +35,5 @@
    * That is needed e.g. to use {@link MapillaryLayer#getInstance()}
    */
-  public static final synchronized void initPlugin() {
+  public static synchronized void initPlugin() {
     if (!isInitialized) {
       System.setProperty("josm.home", "test/data/preferences");
Index: /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/data/RouteRepresentationTest.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/data/RouteRepresentationTest.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/data/RouteRepresentationTest.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.data;
 
@@ -15,13 +16,13 @@
  * Tests if the representation of a route relation is created correctly in the
  * pt_assistant plugin
- * 
+ *
  * @author darya
  *
  */
 public class RouteRepresentationTest extends AbstractTest {
-    
+
     @Test
     public void correctRouteTest() {
-        
+
         /*-
          * Create a [correct] route which has:
@@ -36,11 +37,11 @@
          * way4 (Way)
          * stop5 (platform_exit_only, Relation)
-         * 
+         *
          */
-        
+
         ArrayList<RelationMember> members = new ArrayList<>();
-        
+
         // Create stops:
-        Node n1 = new Node(); 
+        Node n1 = new Node();
         n1.put("name", "Stop1");
         n1.put("public_transport", "stop_position");
@@ -72,5 +73,5 @@
         RelationMember rm6 = new RelationMember("platform_exit_only", n5);
         members.add(rm6);
-                
+
         // Create ways:
         Way w2 = new Way();
@@ -92,24 +93,24 @@
         RelationMember rm10 = new RelationMember("", w7);
         members.add(rm10);
-        
+
         Relation route = new Relation();
         route.setMembers(members);
-        
+
         PTRouteDataManager manager = new PTRouteDataManager(route);
-    
+
         assertEquals(manager.getPTStopCount(), 5);
         assertEquals(manager.getPTWayCount(), 4);
-        
+
     }
-    
+
     @Test
     public void nestedRelationTest() {
-        
+
         // Same as above, but the nested Relation has a Node (only ways are allowed)
-        
+
         ArrayList<RelationMember> members = new ArrayList<>();
-        
+
         // Create stops:
-        Node n1 = new Node(); 
+        Node n1 = new Node();
         n1.put("name", "Stop1");
         n1.put("public_transport", "stop_position");
@@ -141,5 +142,5 @@
         RelationMember rm6 = new RelationMember("platform_exit_only", n5);
         members.add(rm6);
-                
+
         // Create ways:
         Way w2 = new Way();
@@ -161,16 +162,14 @@
         RelationMember rm10 = new RelationMember("", w7);
         members.add(rm10);
-        
-        
+
+
         Relation route = new Relation();
         route.setMembers(members);
-        
+
         PTRouteDataManager manager = new PTRouteDataManager(route);
-        
+
         assertEquals(manager.getFailedMembers().size(), 1);
         assertEquals(manager.getPTStopCount(), 5);
         assertEquals(manager.getPTWayCount(), 3);
-        
     }
-    
 }
Index: /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/data/StopToWayAssignerTest.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/data/StopToWayAssignerTest.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/data/StopToWayAssignerTest.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.data;
 
@@ -14,48 +15,43 @@
 
 public class StopToWayAssignerTest extends AbstractTest {
-	
-	@Test
-	public void test() {
-		
-		File file = new File(AbstractTest.PATH_TO_ONEWAY_BAD_MEMBER_SORTING);
-		DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
-		
-		Relation route = null;
-		for (Relation r: ds.getRelations()) {
-			if (r.getId() == 4552871) {
-				route = r;
-				break;
-			}
-		}
-		
-		PTRouteDataManager manager = new PTRouteDataManager(route);
-		StopToWayAssigner assigner = new StopToWayAssigner(manager.getPTWays());
-		
-		// test with a [correct] stop_position:
-		PTStop ptstop1 = manager.getPTStop(447358573l);
-//		PTWay ptway1 = assigner.get(ptstop1);
-//		Way way1 = ptway1.getWays().get(0);
-		Way way1 = assigner.get(ptstop1);
-		assertEquals(way1.getId(), 26956744l);
-		
-		// test with a [wrong] stop_position:
-		PTStop ptstop2 = manager.getPTStop(427562058l);
-		Way way2 = assigner.get(ptstop2);
-		assertEquals(way2.getId(), 46349880l);
-		
-		// test with a stop_area:
-		PTStop ptstop3 = manager.getPTStop(2987217064l);
-		Way way3 = assigner.get(ptstop3);
-		assertEquals(way3.getId(), 7045925l);
-		
-		// test with a platform without a stop_area:
-		PTStop ptstop4 = manager.getPTStop(3327206909l);
-		Way way4 = assigner.get(ptstop4);
-		assertEquals(way4.getId(), 120277227l);
-		
-		
-	}
-	
-	
 
+    @Test
+    public void test() {
+
+        File file = new File(AbstractTest.PATH_TO_ONEWAY_BAD_MEMBER_SORTING);
+        DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
+
+        Relation route = null;
+        for (Relation r: ds.getRelations()) {
+            if (r.getId() == 4552871) {
+                route = r;
+                break;
+            }
+        }
+
+        PTRouteDataManager manager = new PTRouteDataManager(route);
+        StopToWayAssigner assigner = new StopToWayAssigner(manager.getPTWays());
+
+        // test with a [correct] stop_position:
+        PTStop ptstop1 = manager.getPTStop(447358573L);
+//        PTWay ptway1 = assigner.get(ptstop1);
+//        Way way1 = ptway1.getWays().get(0);
+        Way way1 = assigner.get(ptstop1);
+        assertEquals(way1.getId(), 26956744L);
+
+        // test with a [wrong] stop_position:
+        PTStop ptstop2 = manager.getPTStop(427562058L);
+        Way way2 = assigner.get(ptstop2);
+        assertEquals(way2.getId(), 46349880L);
+
+        // test with a stop_area:
+        PTStop ptstop3 = manager.getPTStop(2987217064L);
+        Way way3 = assigner.get(ptstop3);
+        assertEquals(way3.getId(), 7045925L);
+
+        // test with a platform without a stop_area:
+        PTStop ptstop4 = manager.getPTStop(3327206909L);
+        Way way4 = assigner.get(ptstop4);
+        assertEquals(way4.getId(), 120277227L);
+    }
 }
Index: /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/validation/AdjacentWaysTest.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/validation/AdjacentWaysTest.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/validation/AdjacentWaysTest.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.validation;
 
@@ -18,55 +19,55 @@
 public class AdjacentWaysTest extends AbstractTest {
 
-	@Test
-	public void test1() {
+    @Test
+    public void test1() {
 
-		File file = new File(AbstractTest.PATH_TO_ONEWAY_WRONG_DIRECTION);
-		DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
+        File file = new File(AbstractTest.PATH_TO_ONEWAY_WRONG_DIRECTION);
+        DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
 
-		PTAssistantValidatorTest test = new PTAssistantValidatorTest();
-		long id = 24215210;
-		Way way = (Way) ds.getPrimitiveById(id, OsmPrimitiveType.WAY);
-		
-		assertEquals(RouteUtils.isOnewayForPublicTransport(way), -1);
-		
-		Relation route = null;
-		for (Relation r : ds.getRelations()) {
-			if (r.hasKey("route")) {
-				route = r;
-			}
-		}
-		
-		WayChecker wayChecker = new WayChecker(route, test);
-		Set<Way> set = wayChecker.checkAdjacentWays(way, new HashSet<Way>());
-		
-		assertEquals(set.size(), 1);
+        PTAssistantValidatorTest test = new PTAssistantValidatorTest();
+        long id = 24215210;
+        Way way = (Way) ds.getPrimitiveById(id, OsmPrimitiveType.WAY);
 
-	}
-	
-	@Test
-	public void test2() {
+        assertEquals(RouteUtils.isOnewayForPublicTransport(way), -1);
 
-		File file = new File(AbstractTest.PATH_TO_ONEWAY_WRONG_DIRECTION2);
-		DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
+        Relation route = null;
+        for (Relation r : ds.getRelations()) {
+            if (r.hasKey("route")) {
+                route = r;
+            }
+        }
 
-		PTAssistantValidatorTest test = new PTAssistantValidatorTest();
-		long id = 24215210;
-		Way way = (Way) ds.getPrimitiveById(id, OsmPrimitiveType.WAY);
-		
-		assertEquals(RouteUtils.isOnewayForPublicTransport(way), -1);
-		
-		Relation route = null;
-		for (Relation r : ds.getRelations()) {
-			if (r.hasKey("route")) {
-				route = r;
-			}
-		}
+        WayChecker wayChecker = new WayChecker(route, test);
+        Set<Way> set = wayChecker.checkAdjacentWays(way, new HashSet<Way>());
 
-		WayChecker wayChecker = new WayChecker(route, test);
-		Set<Way> set = wayChecker.checkAdjacentWays(way, new HashSet<Way>());
-		
-		assertEquals(set.size(), 2);
+        assertEquals(set.size(), 1);
 
-	}
+    }
+
+    @Test
+    public void test2() {
+
+        File file = new File(AbstractTest.PATH_TO_ONEWAY_WRONG_DIRECTION2);
+        DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
+
+        PTAssistantValidatorTest test = new PTAssistantValidatorTest();
+        long id = 24215210;
+        Way way = (Way) ds.getPrimitiveById(id, OsmPrimitiveType.WAY);
+
+        assertEquals(RouteUtils.isOnewayForPublicTransport(way), -1);
+
+        Relation route = null;
+        for (Relation r : ds.getRelations()) {
+            if (r.hasKey("route")) {
+                route = r;
+            }
+        }
+
+        WayChecker wayChecker = new WayChecker(route, test);
+        Set<Way> set = wayChecker.checkAdjacentWays(way, new HashSet<Way>());
+
+        assertEquals(set.size(), 2);
+
+    }
 
 }
Index: /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/validation/DirecionTestTest.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/validation/DirecionTestTest.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/validation/DirecionTestTest.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.validation;
 
@@ -19,44 +20,44 @@
 public class DirecionTestTest extends AbstractTest {
 
-	@Test
-	public void testOnewayTrue() {
+    @Test
+    public void testOnewayTrue() {
 
-		File file = new File(AbstractTest.PATH_TO_ONEWAY_WRONG_DIRECTION);
-		DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
+        File file = new File(AbstractTest.PATH_TO_ONEWAY_WRONG_DIRECTION);
+        DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
 
-		PTAssistantValidatorTest test = new PTAssistantValidatorTest();
+        PTAssistantValidatorTest test = new PTAssistantValidatorTest();
 
-		List<TestError> errors = new ArrayList<>();
+        List<TestError> errors = new ArrayList<>();
 
-		for (Relation r : ds.getRelations()) {
-			WayChecker wayChecker = new WayChecker(r, test);
-			wayChecker.performDirectionTest();
-			errors.addAll(wayChecker.getErrors());
-		}
+        for (Relation r : ds.getRelations()) {
+            WayChecker wayChecker = new WayChecker(r, test);
+            wayChecker.performDirectionTest();
+            errors.addAll(wayChecker.getErrors());
+        }
 
-		assertEquals(errors.size(), 2);
-		int onewayErrorCaught = 0;
-		for (TestError e : errors) {
-			if (e.getCode() == PTAssistantValidatorTest.ERROR_CODE_DIRECTION) {
-				onewayErrorCaught++;
-			}
-		}
+        assertEquals(errors.size(), 2);
+        int onewayErrorCaught = 0;
+        for (TestError e : errors) {
+            if (e.getCode() == PTAssistantValidatorTest.ERROR_CODE_DIRECTION) {
+                onewayErrorCaught++;
+            }
+        }
 
-		assertEquals(onewayErrorCaught, 2);
+        assertEquals(onewayErrorCaught, 2);
 
-		boolean detectedErrorsAreCorrect = true;
-		for (TestError e : errors) {
-			if (e.getCode() == PTAssistantValidatorTest.ERROR_CODE_DIRECTION) {
-				@SuppressWarnings("unchecked")
-				Collection<OsmPrimitive> highlighted = (Collection<OsmPrimitive>) e.getHighlighted();
-				for (OsmPrimitive highlightedPrimitive: highlighted) {
-					if (highlightedPrimitive.getId() != 225732678 && highlightedPrimitive.getId() != 24215210) {
-						detectedErrorsAreCorrect = false;
-					}
-				}
-			}
-		}
+        boolean detectedErrorsAreCorrect = true;
+        for (TestError e : errors) {
+            if (e.getCode() == PTAssistantValidatorTest.ERROR_CODE_DIRECTION) {
+                @SuppressWarnings("unchecked")
+                Collection<OsmPrimitive> highlighted = (Collection<OsmPrimitive>) e.getHighlighted();
+                for (OsmPrimitive highlightedPrimitive: highlighted) {
+                    if (highlightedPrimitive.getId() != 225732678 && highlightedPrimitive.getId() != 24215210) {
+                        detectedErrorsAreCorrect = false;
+                    }
+                }
+            }
+        }
 
-		assertTrue(detectedErrorsAreCorrect);
-	}
+        assertTrue(detectedErrorsAreCorrect);
+    }
 }
Index: /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/validation/PlatformAsWayTest.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/validation/PlatformAsWayTest.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/validation/PlatformAsWayTest.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.validation;
 
@@ -14,25 +15,25 @@
 import org.openstreetmap.josm.plugins.pt_assistant.ImportUtils;
 
-public class PlatformAsWayTest extends AbstractTest{
-    
+public class PlatformAsWayTest extends AbstractTest {
+
     @Test
     public void sortingTest() {
         File file = new File(AbstractTest.PATH_TO_PLATFORM_AS_WAY);
         DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
-        
+
         PTAssistantValidatorTest test = new PTAssistantValidatorTest();
-        
+
         List<TestError> errors = new ArrayList<>();
-        
+
         for (Relation r: ds.getRelations()) {
-        	WayChecker wayChecker = new WayChecker(r, test);
-        	wayChecker.performDirectionTest();
-        	wayChecker.performRoadTypeTest();
-        	errors.addAll(wayChecker.getErrors());
-        	RouteChecker routeChecker = new RouteChecker(r, test);
-        	routeChecker.performSortingTest();
-        	errors.addAll(routeChecker.getErrors());
+            WayChecker wayChecker = new WayChecker(r, test);
+            wayChecker.performDirectionTest();
+            wayChecker.performRoadTypeTest();
+            errors.addAll(wayChecker.getErrors());
+            RouteChecker routeChecker = new RouteChecker(r, test);
+            routeChecker.performSortingTest();
+            errors.addAll(routeChecker.getErrors());
         }
-        
+
         assertEquals(errors.size(), 0);
     }
Index: /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/validation/RoadTypeTestTest.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/validation/RoadTypeTestTest.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/validation/RoadTypeTestTest.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.validation;
 
@@ -18,22 +19,22 @@
 
 public class RoadTypeTestTest extends AbstractTest {
-    
+
     @Test
     public void test() {
-        
+
         File file = new File(AbstractTest.PATH_TO_ROAD_TYPE_ERROR);
         DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
-        
+
         PTAssistantValidatorTest test = new PTAssistantValidatorTest();
         List<TestError> errors = new ArrayList<>();
-        
+
         for (Relation r: ds.getRelations()) {
-        	WayChecker wayChecker = new WayChecker(r, test);
-        	wayChecker.performRoadTypeTest();
-        	errors.addAll(wayChecker.getErrors());
+            WayChecker wayChecker = new WayChecker(r, test);
+            wayChecker.performRoadTypeTest();
+            errors.addAll(wayChecker.getErrors());
         }
-        
+
         assertEquals(errors.size(), 2);
-        
+
         for (TestError e: errors) {
             assertEquals(e.getCode(), PTAssistantValidatorTest.ERROR_CODE_ROAD_TYPE);
Index: /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/validation/SegmentCheckerTest.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/validation/SegmentCheckerTest.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/validation/SegmentCheckerTest.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.validation;
 
@@ -13,30 +14,30 @@
 
 public class SegmentCheckerTest extends AbstractTest {
-	
-	@Test
-	public void test() {
-		
-		
-		File file = new File(AbstractTest.PATH_TO_SEGMENT_TEST);
-		DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
-		PTAssistantValidatorTest test = new PTAssistantValidatorTest();
-		
-		Relation route = null;
-		
-		for (Relation r: ds.getRelations()) {
-			if (RouteUtils.isTwoDirectionRoute(r)) {
-				route = r;
-				break;
-			}
-		}
-		
-		SegmentChecker segmentChecker = new SegmentChecker(route, test);
-		segmentChecker.performStopByStopTest();
-		assertEquals(SegmentChecker.getCorrectSegmentCount(), 27);
-		assertEquals(segmentChecker.getErrors().size(), 0);
-		
-		
-		
-		
-	}
+
+    @Test
+    public void test() {
+
+
+        File file = new File(AbstractTest.PATH_TO_SEGMENT_TEST);
+        DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
+        PTAssistantValidatorTest test = new PTAssistantValidatorTest();
+
+        Relation route = null;
+
+        for (Relation r: ds.getRelations()) {
+            if (RouteUtils.isTwoDirectionRoute(r)) {
+                route = r;
+                break;
+            }
+        }
+
+        SegmentChecker segmentChecker = new SegmentChecker(route, test);
+        segmentChecker.performStopByStopTest();
+        assertEquals(SegmentChecker.getCorrectSegmentCount(), 27);
+        assertEquals(segmentChecker.getErrors().size(), 0);
+
+
+
+
+    }
 }
Index: /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/validation/SolitaryStopPositionTest.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/validation/SolitaryStopPositionTest.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/validation/SolitaryStopPositionTest.java	(revision 33055)
@@ -1,8 +1,10 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.validation;
+
+import static org.junit.Assert.assertEquals;
 
 import java.io.File;
 
 import org.junit.Test;
-import static org.junit.Assert.assertEquals;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Node;
@@ -12,34 +14,34 @@
 public class SolitaryStopPositionTest extends AbstractTest {
 
-	@Test
-	public void test1() {
+    @Test
+    public void test1() {
 
-		File file = new File(AbstractTest.PATH_TO_SOLITARY_STOP_POSITION);
-		DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
-		PTAssistantValidatorTest test = new PTAssistantValidatorTest();
+        File file = new File(AbstractTest.PATH_TO_SOLITARY_STOP_POSITION);
+        DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
+        PTAssistantValidatorTest test = new PTAssistantValidatorTest();
 
-		Node platform = null;
-		Node stopPosition = null;
-		for (Node n : ds.getNodes()) {
-			if (n.hasTag("public_transport", "stop_position")) {
-				stopPosition = n;
-			}
-			if (n.hasTag("public_transport", "platform")) {
-				platform = n;
-			}
-		}
+        Node platform = null;
+        Node stopPosition = null;
+        for (Node n : ds.getNodes()) {
+            if (n.hasTag("public_transport", "stop_position")) {
+                stopPosition = n;
+            }
+            if (n.hasTag("public_transport", "platform")) {
+                platform = n;
+            }
+        }
 
-		NodeChecker checkerPlatform = new NodeChecker(platform, test);
-		checkerPlatform.performPlatformPartOfWayTest();
-		assertEquals(checkerPlatform.getErrors().size(), 1);
-		assertEquals(checkerPlatform.getErrors().get(0).getCode(),
-				PTAssistantValidatorTest.ERROR_CODE_PLATFORM_PART_OF_HIGHWAY);
+        NodeChecker checkerPlatform = new NodeChecker(platform, test);
+        checkerPlatform.performPlatformPartOfWayTest();
+        assertEquals(checkerPlatform.getErrors().size(), 1);
+        assertEquals(checkerPlatform.getErrors().get(0).getCode(),
+                PTAssistantValidatorTest.ERROR_CODE_PLATFORM_PART_OF_HIGHWAY);
 
-		NodeChecker checkerStopPosition = new NodeChecker(stopPosition, test);
-		checkerStopPosition.performSolitaryStopPositionTest();
-		assertEquals(checkerStopPosition.getErrors().size(), 1);
-		assertEquals(checkerStopPosition.getErrors().get(0).getCode(),
-				PTAssistantValidatorTest.ERROR_CODE_SOLITARY_STOP_POSITION);
+        NodeChecker checkerStopPosition = new NodeChecker(stopPosition, test);
+        checkerStopPosition.performSolitaryStopPositionTest();
+        assertEquals(checkerStopPosition.getErrors().size(), 1);
+        assertEquals(checkerStopPosition.getErrors().get(0).getCode(),
+                PTAssistantValidatorTest.ERROR_CODE_SOLITARY_STOP_POSITION);
 
-	}
+    }
 }
Index: /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/validation/SortingTestTest.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/validation/SortingTestTest.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/validation/SortingTestTest.java	(revision 33055)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.validation;
 
@@ -20,14 +21,14 @@
         File file = new File(AbstractTest.PATH_TO_DL131_BEFORE);
         DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
-        
+
         PTAssistantValidatorTest test = new PTAssistantValidatorTest();
 
         List<TestError> errors = new ArrayList<>();
-        
+
         for (Relation r: ds.getRelations()) {
-        	RouteChecker routeChecker = new RouteChecker(r, test);
-        	routeChecker.performSortingTest();
-        	errors.addAll(routeChecker.getErrors());
-        	
+            RouteChecker routeChecker = new RouteChecker(r, test);
+            routeChecker.performSortingTest();
+            errors.addAll(routeChecker.getErrors());
+
         }
 
@@ -41,14 +42,14 @@
         File file = new File(AbstractTest.PATH_TO_DL131_AFTER);
         DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
-        
+
         PTAssistantValidatorTest test = new PTAssistantValidatorTest();
 
         List<TestError> errors = new ArrayList<>();
-        
+
         for (Relation r: ds.getRelations()) {
-        	RouteChecker routeChecker = new RouteChecker(r, test);
-        	routeChecker.performSortingTest();
-        	errors.addAll(routeChecker.getErrors());
-        	
+            RouteChecker routeChecker = new RouteChecker(r, test);
+            routeChecker.performSortingTest();
+            errors.addAll(routeChecker.getErrors());
+
         }
 
@@ -80,13 +81,13 @@
         File file = new File(AbstractTest.PATH_TO_DL286_AFTER);
         DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
-        
+
         PTAssistantValidatorTest test = new PTAssistantValidatorTest();
 
         List<TestError> errors = new ArrayList<>();
-        
+
         for (Relation r: ds.getRelations()) {
-        	RouteChecker routeChecker = new RouteChecker(r, test);
-        	routeChecker.performSortingTest();
-        	errors.addAll(routeChecker.getErrors());
+            RouteChecker routeChecker = new RouteChecker(r, test);
+            routeChecker.performSortingTest();
+            errors.addAll(routeChecker.getErrors());
         }
 
Index: /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/validation/StopCheckerTest.java
===================================================================
--- /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/validation/StopCheckerTest.java	(revision 33054)
+++ /applications/editors/josm/plugins/pt_assistant/test/unit/org/openstreetmap/josm/plugins/pt_assistant/validation/StopCheckerTest.java	(revision 33055)
@@ -1,8 +1,9 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pt_assistant.validation;
 
 import java.io.File;
 
+import org.junit.Assert;
 import org.junit.Test;
-import org.junit.Assert;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Node;
@@ -13,101 +14,95 @@
 public class StopCheckerTest extends AbstractTest {
 
-	@Test
-	public void nodePartOfStopAreaTest() {
+    @Test
+    public void nodePartOfStopAreaTest() {
 
-		// check if stop positions or platforms are in any stop_area relation:
-		
-		File file = new File(AbstractTest.PATH_TO_STOP_AREA_MEMBERS);
-		DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
-		PTAssistantValidatorTest test = new PTAssistantValidatorTest();
-		Node node = null;
-		
-		for (Node n : ds.getNodes()) {
-			if (n.hasTag("public_transport", "stop_position") | n.hasTag("public_transport", "platform")) {
-				node = n;
-			}
-		}
+        // check if stop positions or platforms are in any stop_area relation:
 
-		NodeChecker nodeChecker = new NodeChecker(node, test);
-		nodeChecker.performNodePartOfStopAreaTest();
-		Assert.assertEquals(nodeChecker.getErrors().size(), 1);
-		Assert.assertEquals(nodeChecker.getErrors().get(0).getCode(),
-				PTAssistantValidatorTest.ERROR_CODE_NOT_PART_OF_STOP_AREA);
-	}
-	
+        File file = new File(AbstractTest.PATH_TO_STOP_AREA_MEMBERS);
+        DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
+        PTAssistantValidatorTest test = new PTAssistantValidatorTest();
+        Node node = null;
 
+        for (Node n : ds.getNodes()) {
+            if (n.hasTag("public_transport", "stop_position") | n.hasTag("public_transport", "platform")) {
+                node = n;
+            }
+        }
 
-	@Test
-	public void stopAreaRelationsTest() {
-		
-		// Check if stop positions belong the same routes as related platform(s)
-		
-		File file = new File(AbstractTest.PATH_TO_STOP_AREA_RELATIONS);
-		DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
-		PTAssistantValidatorTest test = new PTAssistantValidatorTest();
-		Relation stopArea = null;
-		
-		for (Relation r : ds.getRelations()) {
-			if (r.hasTag("public_transport", "stop_area")) {
-				stopArea = r;
-			}
-		}
-		
-		StopChecker stopChecker = new StopChecker(stopArea, test);
-		stopChecker.performStopAreaRelationsTest();
-		Assert.assertEquals(stopChecker.getErrors().size(), 1);
-		Assert.assertEquals(stopChecker.getErrors().get(0).getCode(),
-				PTAssistantValidatorTest.ERROR_CODE_STOP_AREA_COMPARE_RELATIONS);		
-	}
-	
+        NodeChecker nodeChecker = new NodeChecker(node, test);
+        nodeChecker.performNodePartOfStopAreaTest();
+        Assert.assertEquals(nodeChecker.getErrors().size(), 1);
+        Assert.assertEquals(nodeChecker.getErrors().get(0).getCode(),
+                PTAssistantValidatorTest.ERROR_CODE_NOT_PART_OF_STOP_AREA);
+    }
 
-	@Test
-	public void stopAreaStopPositionTest() {
-		
-		// Check if stop area relation has at least one stop position. 
-		
-		File file = new File(AbstractTest.PATH_TO_STOP_AREA_NO_STOPS);
-		DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
-		PTAssistantValidatorTest test = new PTAssistantValidatorTest();
-		Relation stopArea = null;
+    @Test
+    public void stopAreaRelationsTest() {
 
-		for (Relation r : ds.getRelations()) {
-			if (r.hasTag("public_transport", "stop_area")) {
-				stopArea = r;
-			}
-		}
-		
-		StopChecker stopChecker = new StopChecker(stopArea, test);
-		stopChecker.performStopAreaStopPositionTest();
-		Assert.assertEquals(stopChecker.getErrors().size(), 1);
-		Assert.assertEquals(stopChecker.getErrors().get(0).getCode(),
-				PTAssistantValidatorTest.ERROR_CODE_STOP_AREA_NO_STOPS);
+        // Check if stop positions belong the same routes as related platform(s)
 
-	}
-	
+        File file = new File(AbstractTest.PATH_TO_STOP_AREA_RELATIONS);
+        DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
+        PTAssistantValidatorTest test = new PTAssistantValidatorTest();
+        Relation stopArea = null;
 
-	@Test
-	public void stopAreaPlatformTest() {
-		
-		// Check if stop area relation has at least one platform. 
-		
-		File file = new File(AbstractTest.PATH_TO_STOP_AREA_NO_PLATFORMS);
-		DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
-		PTAssistantValidatorTest test = new PTAssistantValidatorTest();
-		Relation stopArea = null;
+        for (Relation r : ds.getRelations()) {
+            if (r.hasTag("public_transport", "stop_area")) {
+                stopArea = r;
+            }
+        }
 
-		for (Relation r : ds.getRelations()) {
-			if (r.hasTag("public_transport", "stop_area")) {
-				stopArea = r;
-			}
-		}
-		
-		StopChecker stopChecker = new StopChecker(stopArea, test);
-		stopChecker.performStopAreaPlatformTest();
-		Assert.assertEquals(stopChecker.getErrors().size(), 1);
-		Assert.assertEquals(stopChecker.getErrors().get(0).getCode(),
-				PTAssistantValidatorTest.ERROR_CODE_STOP_AREA_NO_PLATFORM);
+        StopChecker stopChecker = new StopChecker(stopArea, test);
+        stopChecker.performStopAreaRelationsTest();
+        Assert.assertEquals(stopChecker.getErrors().size(), 1);
+        Assert.assertEquals(stopChecker.getErrors().get(0).getCode(),
+                PTAssistantValidatorTest.ERROR_CODE_STOP_AREA_COMPARE_RELATIONS);
+    }
 
-	}
+    @Test
+    public void stopAreaStopPositionTest() {
 
+        // Check if stop area relation has at least one stop position.
+
+        File file = new File(AbstractTest.PATH_TO_STOP_AREA_NO_STOPS);
+        DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
+        PTAssistantValidatorTest test = new PTAssistantValidatorTest();
+        Relation stopArea = null;
+
+        for (Relation r : ds.getRelations()) {
+            if (r.hasTag("public_transport", "stop_area")) {
+                stopArea = r;
+            }
+        }
+
+        StopChecker stopChecker = new StopChecker(stopArea, test);
+        stopChecker.performStopAreaStopPositionTest();
+        Assert.assertEquals(stopChecker.getErrors().size(), 1);
+        Assert.assertEquals(stopChecker.getErrors().get(0).getCode(),
+                PTAssistantValidatorTest.ERROR_CODE_STOP_AREA_NO_STOPS);
+    }
+
+    @Test
+    public void stopAreaPlatformTest() {
+
+        // Check if stop area relation has at least one platform.
+
+        File file = new File(AbstractTest.PATH_TO_STOP_AREA_NO_PLATFORMS);
+        DataSet ds = ImportUtils.importOsmFile(file, "testLayer");
+        PTAssistantValidatorTest test = new PTAssistantValidatorTest();
+        Relation stopArea = null;
+
+        for (Relation r : ds.getRelations()) {
+            if (r.hasTag("public_transport", "stop_area")) {
+                stopArea = r;
+            }
+        }
+
+        StopChecker stopChecker = new StopChecker(stopArea, test);
+        stopChecker.performStopAreaPlatformTest();
+        Assert.assertEquals(stopChecker.getErrors().size(), 1);
+        Assert.assertEquals(stopChecker.getErrors().get(0).getCode(),
+                PTAssistantValidatorTest.ERROR_CODE_STOP_AREA_NO_PLATFORM);
+
+    }
 }
