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 32252)
+++ applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/IncompleteMembersDownloadDialog.java	(revision 32252)
@@ -0,0 +1,93 @@
+package org.openstreetmap.josm.plugins.pt_assistant.gui;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import javax.swing.JCheckBox;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+
+public class IncompleteMembersDownloadDialog extends JPanel {
+
+	private static final long serialVersionUID = -4275151182361040329L;
+
+	// 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
+	};
+
+	// by default, the user should be asked
+	private static ASK_TO_FETCH askToFetch = ASK_TO_FETCH.DO_ASK;
+
+	private long relationId;
+	String message;
+	private JCheckBox checkbox;
+	private String[] options;
+	private int selectedOption;
+
+	public IncompleteMembersDownloadDialog(long id) {
+		relationId = id;
+		selectedOption = Integer.MIN_VALUE;
+
+		message = tr("The relation (id=" + relationId
+				+ ") has incomplete members.\nThey need to be downloaded to proceed with validation of this relation.\nDo you want to download incomplete members?");
+		checkbox = new JCheckBox(tr("Remember my choice and don't 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() {
+
+		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;
+		}
+
+		// this.createDialog(); // FIXME
+		
+
+		Object[] params = {message, checkbox};
+		selectedOption = JOptionPane.showOptionDialog(this, params, tr("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;
+	}
+
+	private void createDialog() {
+		if (!SwingUtilities.isEventDispatchThread()) {
+			Object[] params = {message, checkbox};
+			selectedOption = JOptionPane.showOptionDialog(null, params, tr("Fetch Request"), JOptionPane.YES_NO_OPTION,
+					JOptionPane.QUESTION_MESSAGE, null, options, 0);
+		} else {
+			SwingUtilities.invokeLater(new Runnable() {
+				@Override
+				public void run() {
+					createDialog();
+				}
+			});
+
+		}
+	}
+
+}
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 32251)
+++ applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/utils/RouteUtils.java	(revision 32252)
@@ -24,16 +24,4 @@
  */
 public class RouteUtils {
-
-	// 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 ASK_TO_FETCH askToFetch = ASK_TO_FETCH.DO_ASK;
-	
-	// checks that the same relation is only fetched once
-	private static Relation lastRelationToFetch = null;
 
 	private RouteUtils() {
@@ -117,4 +105,9 @@
 	 * direction of the way (i.e. one-way roads) is irrelevant for this test.
 	 * 
+	 * TODO: this test is duplicated in WayChecker, remove it here when the old
+	 * implementation is not needed anymore.
+	 * 
+	 * @deprecated
+	 * 
 	 * @param way
 	 *            to be checked
@@ -137,99 +130,9 @@
 	}
 
-	/**
-	 * Checks if all members of a relation are complete. If not, the user is
-	 * asked to confirm the permission to fetch them, and they are fetched. The
-	 * completeness of the relation itself is not checked.
-	 * 
-	 * @param r
-	 *            relation
-	 * @return true if all relation members are complete (or fetched), false
-	 *         otherwise (including if the user denies permission to download
-	 *         data)
-	 * TODO: what should be done in case the connection to the server is broken
-	 */
-	public static boolean ensureMemberCompleteness(Relation r) {
-		
-		if (r == null) {
-			return false;
-		}
-
-		boolean isComplete = true;
-
-		// check if there is at least one incomplete relation member:
-		for (RelationMember rm : r.getMembers()) {
-			if ((rm.isNode() && rm.getNode().isIncomplete()) || (rm.isWay() && rm.getWay().isIncomplete())
-					|| (rm.isRelation() && rm.getRelation().isIncomplete())) {
-				isComplete = false;
-				
-				break;
-				
-			}
-		}
-
-		if (!isComplete && !r.equals(lastRelationToFetch)) {
-
-			int userInput = Integer.MIN_VALUE;
-			
-
-			if (askToFetch == ASK_TO_FETCH.DO_ASK) {
-				String message = tr("The relation (id=" + r.getId()
-						+ ") has incomplete members.\nThey need to be downloaded to proceed with validation of this relation.\nDo you want to download incomplete members?");
-				JCheckBox checkbox = new JCheckBox(tr("Remember my choice and don't ask me again in this session"));
-				Object[] params = { message, checkbox };
-				String[] options = { tr("Yes"), tr("No") };
-				// ask the user:
-				userInput = JOptionPane.showOptionDialog(null, params, tr("Fetch Request"), JOptionPane.YES_NO_OPTION,
-						JOptionPane.QUESTION_MESSAGE, null, options, 0);
-				
-
-				// if the user does not want to be asked:
-				if (checkbox.isSelected()) {
-					if (userInput == 0) {
-						askToFetch = ASK_TO_FETCH.DONT_ASK_AND_FETCH;
-					} else {
-						askToFetch = ASK_TO_FETCH.DONT_ASK_AND_DONT_FETCH;
-					}
-				}
-			}
-
-			// if the user does want to fetch:
-			if (userInput == 0 || askToFetch == ASK_TO_FETCH.DONT_ASK_AND_FETCH) {
-//				List<PrimitiveId> list = new ArrayList<>(1);
-//				list.add(r);
-				List<PrimitiveId> list = new ArrayList<>();
-				for (OsmPrimitive primitive: r.getIncompleteMembers()) {
-					list.add(primitive);
-				}
-				
-				Thread t = new Thread (new IncompleteMembersDownloader(list));
-				t.run();
-				try {
-					t.join();
-				} catch (InterruptedException e) {
-					// TODO Auto-generated catch block
-					e.printStackTrace();
-				}
-
-				
-				
-//				DownloadPrimitiveAction.processItems(false, list, false, true);
-				JOptionPane.showMessageDialog(null, "download expected to be finished");
-				isComplete = true;
-				lastRelationToFetch = r;
-
-			}
-
-		}
-
-		return isComplete;
-	}
-	
-	
 	public static boolean hasIncompleteMembers(Relation r) {
 		if (r == null) {
 			return true;
 		}
-		for (RelationMember rm: r.getMembers()) {
+		for (RelationMember rm : r.getMembers()) {
 			if ((rm.isNode() && rm.getNode().isIncomplete()) || (rm.isWay() && rm.getWay().isIncomplete())
 					|| (rm.isRelation() && rm.getRelation().isIncomplete())) {
@@ -237,23 +140,7 @@
 			}
 		}
-		
+
 		return false;
 	}
-	
-//	/**
-//	 * TODO: this is temporal
-//	 */
-//	public static String getFetch() {
-//		if (askToFetch == ASK_TO_FETCH.DO_ASK) {
-//			return "do ask";
-//		} 
-//		if (askToFetch == ASK_TO_FETCH.DONT_ASK_AND_FETCH) {
-//			return "don;t ask and fetch";
-//		}
-//		return "don't ask and don't fetch";
-//	}
-	
 
 }
-
-
Index: applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/DirectionTest.java
===================================================================
--- applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/DirectionTest.java	(revision 32251)
+++ applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/DirectionTest.java	(revision 32252)
@@ -43,9 +43,4 @@
 		}
 
-//		boolean isComplete = RouteUtils.ensureMemberCompleteness(r);
-//		if (!isComplete) {
-//			return;
-//		}
-		
 		if (RouteUtils.hasIncompleteMembers(r)) {
 			return;
Index: applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/GapTest.java
===================================================================
--- applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/GapTest.java	(revision 32251)
+++ applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/GapTest.java	(revision 32252)
@@ -44,9 +44,4 @@
 		}
 
-//		boolean isComplete = RouteUtils.ensureMemberCompleteness(r);
-//		if (!isComplete) {
-//			return;
-//		}
-		
 		if (RouteUtils.hasIncompleteMembers(r)) {
 			return;
Index: applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/PTAssitantValidatorTest.java
===================================================================
--- applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/PTAssitantValidatorTest.java	(revision 32251)
+++ applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/PTAssitantValidatorTest.java	(revision 32252)
@@ -25,4 +25,9 @@
 public class PTAssitantValidatorTest extends Test {
 
+	public static final int ERROR_CODE_SORTING = 3711;
+	// public static final int ERROR_CODE_OVERSHOOT = 3712;
+	// public static final int ERROR_CODE_SPLITTING = 3713;
+	// public static final int ERROR_CODE_OTHER_GAP = 3719;
+	public static final int ERROR_CODE_ROAD_TYPE = 3721;
 	public static final int ERROR_CODE_DIRECTION = 3731;
 
@@ -30,4 +35,5 @@
 		super(tr("Public Transport Assistant tests"),
 				tr("Check if route relations are compatible with public transport version 2"));
+
 	}
 
@@ -47,9 +53,15 @@
 		}
 
-		performDummyTest(r);
-
-
-
-
+		// Check individual ways using the oneway direction test and the road
+		// type test:
+		WayChecker wayChecker = new WayChecker(r, this);
+		this.errors.addAll(wayChecker.getErrors());
+		
+		// TODO: ask user if the found problems should be fixed
+		
+		// Check if the relation is correct, or only has a wrong sorting order:
+		RouteChecker routeChecker = new RouteChecker(r, this);
+		this.errors.addAll(routeChecker.getErrors());
+		
 
 	}
@@ -80,5 +92,5 @@
 			return true;
 		}
-		
+
 		return false;
 	}
@@ -96,54 +108,10 @@
 		return null;
 	}
-	
-	private void performDirectionTest(Relation r) {
-		List<RelationMember> waysToCheck = new ArrayList<>();
 
-		for (RelationMember rm : r.getMembers()) {
-			if (RouteUtils.isPTWay(rm) && rm.getType().equals(OsmPrimitiveType.WAY)) {
-				waysToCheck.add(rm);
-			}
-		}
-
-		if (waysToCheck.isEmpty()) {
-			return;
-		}
-		
-		WayConnectionTypeCalculator connectionTypeCalculator = new WayConnectionTypeCalculator();
-		final List<WayConnectionType> links = connectionTypeCalculator.updateLinks(waysToCheck);
-
-		for (int i = 0; i < links.size(); i++) {
-			if ((OsmUtils.isTrue(waysToCheck.get(i).getWay().get("oneway"))
-					&& links.get(i).direction.equals(WayConnectionType.Direction.BACKWARD))
-					|| (OsmUtils.isReversed(waysToCheck.get(i).getWay().get("oneway"))
-							&& links.get(i).direction.equals(WayConnectionType.Direction.FORWARD))) {
-
-				// At this point, the PTWay is going against the oneway
-				// direction. Check if this road allows buses to disregard
-				// the oneway restriction:
-
-				if (!waysToCheck.get(i).getWay().hasTag("busway", "lane")
-						&& !waysToCheck.get(i).getWay().hasTag("oneway:bus", "no")
-						&& !waysToCheck.get(i).getWay().hasTag("busway", "opposite_lane")
-						&& !waysToCheck.get(i).getWay().hasTag("oneway:psv", "no")
-						&& !waysToCheck.get(i).getWay().hasTag("trolley_wire", "backward")) {
-					List<Relation> primitives = new ArrayList<>(1);
-					primitives.add(r);
-					List<Way> highlighted = new ArrayList<>(1);
-					highlighted.add(waysToCheck.get(i).getWay());
-					errors.add(new TestError(this, Severity.WARNING,
-							tr("PT: Route passes a oneway road in wrong direction"), ERROR_CODE_DIRECTION, primitives,
-							highlighted));
-					return;
-				}
-
-			}
-		}
-	}
-	
 	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));
+		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/RoadTypeTest.java
===================================================================
--- applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/RoadTypeTest.java	(revision 32251)
+++ applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/RoadTypeTest.java	(revision 32252)
@@ -34,9 +34,4 @@
 			return;
 		}
-
-//		boolean isComplete = RouteUtils.ensureMemberCompleteness(r);
-//		if (!isComplete) {
-//			return;
-//		}
 		
 		if (RouteUtils.hasIncompleteMembers(r)) {
@@ -47,5 +42,5 @@
 
 		for (RelationMember rm : members) {
-			if (RouteUtils.isPTWay(rm)) {
+			if (RouteUtils.isPTWay(rm) && rm.getType().equals(OsmPrimitiveType.WAY)) {
 
 				Way way = rm.getWay();
@@ -61,5 +56,5 @@
 						isCorrectRoadType = false;
 					}
-				} else if (r.hasTag("route", "tram")) {
+				} else if (r.hasTag("route", "tram") && !way.hasTag("railway", "tram")) {
 					if (!r.hasTag("railway", "tram")) {
 						isCorrectRoadType = false;
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 32252)
+++ applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/RouteChecker.java	(revision 32252)
@@ -0,0 +1,107 @@
+package org.openstreetmap.josm.plugins.pt_assistant.validation;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.data.validation.Severity;
+import org.openstreetmap.josm.data.validation.Test;
+import org.openstreetmap.josm.data.validation.TestError;
+import org.openstreetmap.josm.gui.dialogs.relation.sort.RelationSorter;
+import org.openstreetmap.josm.gui.dialogs.relation.sort.WayConnectionType;
+import org.openstreetmap.josm.gui.dialogs.relation.sort.WayConnectionTypeCalculator;
+import org.openstreetmap.josm.plugins.pt_assistant.utils.RouteUtils;
+
+public class RouteChecker {
+
+	// test which created this WayChecker:
+	private final Test test;
+
+	// relation that is checked:
+	private Relation relation;
+	
+	// stores all found errors (on way level):
+	private ArrayList<TestError> errors = new ArrayList<>();
+	
+	List<RelationMember> sortedMembers;
+
+	public RouteChecker(Relation r, Test t) {
+
+		this.test = t;
+		this.relation = r;
+		
+		performSortingTest();
+
+	}
+
+	private void performSortingTest() {
+
+		final List<RelationMember> waysToCheck = new ArrayList<>();
+		for (RelationMember rm : relation.getMembers()) {
+
+			if (RouteUtils.isPTWay(rm) && rm.getType().equals(OsmPrimitiveType.WAY)) {
+				waysToCheck.add(rm);
+			}
+		}
+
+		if (waysToCheck.isEmpty()) {
+			return;
+		}
+		
+		if (hasGap(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"), PTAssitantValidatorTest.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;
+
+			}
+		}
+
+		return false;
+	}
+	
+	public List<TestError> getErrors() {
+
+		return errors;
+	}
+	
+	public List<RelationMember> getSortedMembers() {
+		
+		return sortedMembers;
+		
+	}
+
+}
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 32252)
+++ applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/WayChecker.java	(revision 32252)
@@ -0,0 +1,184 @@
+package org.openstreetmap.josm.plugins.pt_assistant.validation;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
+import org.openstreetmap.josm.data.osm.OsmUtils;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.validation.Severity;
+import org.openstreetmap.josm.data.validation.Test;
+import org.openstreetmap.josm.data.validation.TestError;
+import org.openstreetmap.josm.gui.dialogs.relation.sort.WayConnectionType;
+import org.openstreetmap.josm.gui.dialogs.relation.sort.WayConnectionTypeCalculator;
+import org.openstreetmap.josm.plugins.pt_assistant.utils.RouteUtils;
+
+/**
+ * Performs the DirectionTest and RoadTypeTest at the level of single ways
+ * 
+ * @author darya
+ *
+ */
+public class WayChecker {
+
+	// test which created this WayChecker:
+	private final Test test;
+
+	// relation that is checked:
+	private Relation relation;
+
+	// stores all found errors (on way level):
+	private ArrayList<TestError> errors = new ArrayList<>();
+
+	// stores all ways that were found wrong and need to be removed:
+	private ArrayList<Way> wrongWays = new ArrayList<>();
+
+	public WayChecker(Relation r, Test test) {
+
+		this.test = test;
+		this.relation = r;
+		
+		this.performDirectionTest();
+		this.performRoadTypeTest();
+		
+	}
+
+	private void performRoadTypeTest() {
+
+		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;
+				if (relation.hasTag("route", "bus") || relation.hasTag("route", "share_taxi")) {
+					if (!isWaySuitableForBuses(way)) {
+						isCorrectRoadType = false;
+					}
+				} else if (relation.hasTag("route", "trolleybus")) {
+					if (!(isWaySuitableForBuses(way) && way.hasTag("trolley_wire", "yes"))) {
+						isCorrectRoadType = false;
+					}
+				} else if (relation.hasTag("route", "tram")) {
+					if (!relation.hasTag("railway", "tram") && !way.hasTag("railway", "tram")) {
+						isCorrectRoadType = false;
+					}
+				} else if (relation.hasTag("route", "subway")) {
+					if (!relation.hasTag("railway", "subway")) {
+						isCorrectRoadType = false;
+					}
+				} else if (relation.hasTag("route", "light_rail")) {
+					if (!relation.hasTag("raiilway", "subway")) {
+						isCorrectRoadType = false;
+					}
+				} else if (relation.hasTag("route", "light_rail")) {
+					if (!relation.hasTag("railway", "light_rail")) {
+						isCorrectRoadType = false;
+					}
+				} else if (relation.hasTag("route", "train")) {
+					if (!relation.hasTag("railway", "train")) {
+						isCorrectRoadType = false;
+					}
+				}
+
+				if (!isCorrectRoadType) {
+
+					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"),
+							PTAssitantValidatorTest.ERROR_CODE_ROAD_TYPE, primitives, highlighted);
+					errors.add(e);
+
+				}
+			}
+		}
+
+	}
+
+	private void performDirectionTest() {
+
+		List<RelationMember> waysToCheck = new ArrayList<>();
+
+		for (RelationMember rm : relation.getMembers()) {
+			if (RouteUtils.isPTWay(rm) && rm.getType().equals(OsmPrimitiveType.WAY)) {
+				waysToCheck.add(rm);
+			}
+		}
+
+		if (waysToCheck.isEmpty()) {
+			return;
+		}
+
+		WayConnectionTypeCalculator connectionTypeCalculator = new WayConnectionTypeCalculator();
+		final List<WayConnectionType> links = connectionTypeCalculator.updateLinks(waysToCheck);
+
+		for (int i = 0; i < links.size(); i++) {
+			if ((OsmUtils.isTrue(waysToCheck.get(i).getWay().get("oneway"))
+					&& links.get(i).direction.equals(WayConnectionType.Direction.BACKWARD))
+					|| (OsmUtils.isReversed(waysToCheck.get(i).getWay().get("oneway"))
+							&& links.get(i).direction.equals(WayConnectionType.Direction.FORWARD))) {
+
+				// At this point, the PTWay is going against the oneway
+				// direction. Check if this road allows buses to disregard
+				// the oneway restriction:
+
+				if (!waysToCheck.get(i).getWay().hasTag("busway", "lane")
+						&& !waysToCheck.get(i).getWay().hasTag("oneway:bus", "no")
+						&& !waysToCheck.get(i).getWay().hasTag("busway", "opposite_lane")
+						&& !waysToCheck.get(i).getWay().hasTag("oneway:psv", "no")
+						&& !waysToCheck.get(i).getWay().hasTag("trolley_wire", "backward")) {
+					List<Relation> primitives = new ArrayList<>(1);
+					primitives.add(relation);
+					List<Way> highlighted = new ArrayList<>(1);
+					highlighted.add(waysToCheck.get(i).getWay());
+					TestError e = new TestError(this.test, Severity.WARNING,
+							tr("PT: Route passes a oneway road in wrong direction"),
+							PTAssitantValidatorTest.ERROR_CODE_DIRECTION, primitives, highlighted);
+					this.errors.add(e);
+					return;
+				}
+
+			}
+		}
+
+	}
+
+	public List<TestError> getErrors() {
+
+		return errors;
+	}
+
+	/**
+	 * 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 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;
+		}
+
+		return false;
+	}
+
+}
