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 32258)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/IncompleteMembersDownloadDialog.java	(revision 32259)
@@ -21,5 +21,4 @@
 	private static ASK_TO_FETCH askToFetch = ASK_TO_FETCH.DO_ASK;
 
-	private long relationId;
 	String message;
 	private JCheckBox checkbox;
@@ -28,8 +27,7 @@
 
 	public IncompleteMembersDownloadDialog(long id) {
-		relationId = id;
 		selectedOption = Integer.MIN_VALUE;
 
-		message = tr("The relation (id=" + relationId
+		message = tr("The relation (id=" + id
 				+ ") 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"));
@@ -61,5 +59,5 @@
 
 		Object[] params = {message, checkbox};
-		selectedOption = JOptionPane.showOptionDialog(this, params, tr("Fetch Request"), JOptionPane.YES_NO_OPTION,
+		selectedOption = JOptionPane.showOptionDialog(this, params, tr("PT_Assistant Fetch Request"), JOptionPane.YES_NO_OPTION,
 				JOptionPane.QUESTION_MESSAGE, null, options, 0);
 		
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 32259)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/gui/ProceedDialog.java	(revision 32259)
@@ -0,0 +1,140 @@
+package org.openstreetmap.josm.plugins.pt_assistant.gui;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+
+import javax.swing.BoxLayout;
+import javax.swing.ButtonGroup;
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+
+public class ProceedDialog extends JPanel {
+
+	private static final long serialVersionUID = 2986537034076698693L;
+
+	private 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
+	private static ASK_TO_PROCEED askToProceed = ASK_TO_PROCEED.DO_ASK;
+
+	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) {
+
+		panel = new JPanel();
+		panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
+		
+		JLabel label1 = new JLabel(tr("PT_Assistant plugin found that this relation (id=" + id + ") has errors:"));
+		panel.add(label1);
+		label1.setAlignmentX(Component.LEFT_ALIGNMENT);
+		
+		if (numberOfDirectionErrors != 0) {
+			JLabel label2 = new JLabel("     " + numberOfDirectionErrors + tr(" direction errors"));
+			panel.add(label2);
+			label2.setAlignmentX(Component.LEFT_ALIGNMENT);
+		}
+		
+		if (numberOfRoadTypeErrors != 0) {
+			JLabel label3 = new JLabel("     " + numberOfRoadTypeErrors + tr(" road type errors"));
+			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);
+
+		radioButtonFixAutomatically = new JRadioButton("Fix all errors automatically and proceed",
+				true);
+		radioButtonFixManually = new JRadioButton(
+				"I will fix the erros manually and click the button to proceed");
+		radioButtonDontFix = new JRadioButton("Do not fix anything and proceed with further tests");
+		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 don't 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";
+
+		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() {
+
+		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;
+		}
+
+		// FIXME: change to avoid EDT errors
+		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;
+			}
+		}
+
+		return -1;
+	}
+
+}
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 32258)
+++ /applications/editors/josm/plugins/pt_assistant/src/org/openstreetmap/josm/plugins/pt_assistant/validation/PTAssitantValidatorTest.java	(revision 32259)
@@ -8,7 +8,10 @@
 import javax.swing.JOptionPane;
 
+import org.openstreetmap.josm.command.ChangeCommand;
 import org.openstreetmap.josm.command.Command;
+import org.openstreetmap.josm.command.SequenceCommand;
+import org.openstreetmap.josm.data.osm.AbstractPrimitive;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
 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;
@@ -17,8 +20,8 @@
 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.gui.dialogs.relation.sort.RelationSorter;
 import org.openstreetmap.josm.plugins.pt_assistant.actions.IncompleteMembersDownloadThread;
 import org.openstreetmap.josm.plugins.pt_assistant.gui.IncompleteMembersDownloadDialog;
+import org.openstreetmap.josm.plugins.pt_assistant.gui.ProceedDialog;
 import org.openstreetmap.josm.plugins.pt_assistant.utils.RouteUtils;
 
@@ -26,7 +29,4 @@
 
 	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;
@@ -57,11 +57,9 @@
 		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());
-		
+
+		if (!this.errors.isEmpty()) {
+			this.proceedAfterWayCheckerErrors(r);
+		}
+
 
 	}
@@ -97,8 +95,63 @@
 
 	/**
+	 * Gets user input after errors were detected by WayChecker (direction
+	 * errors and road type errors)
+	 */
+	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++;
+			}
+		}
+
+		ProceedDialog proceedDialog = new ProceedDialog(r.getId(), numberOfDirectionErrors, numberOfRoadTypeErrors);
+
+		int userInput = proceedDialog.getUserSelection();
+
+		if (userInput == 0) {
+			for (TestError e : this.errors) {
+				fixError(e);
+			}
+			proceedWithSorting(r);
+			return;
+		}
+
+		if (userInput == 1) {
+			// TODO
+			JOptionPane.showMessageDialog(null, "This is not implemented yet!");
+			return;
+		}
+
+		if (userInput == 2) {
+			proceedWithSorting(r);
+		}
+
+		// if userInput==-1 (i.e. no input), do nothing and stop testing of the
+		// route.
+
+	}
+	
+	private void proceedWithSorting(Relation r) {
+		// Check if the relation is correct, or only has a wrong sorting order:
+		RouteChecker routeChecker = new RouteChecker(r, this);
+		this.errors.addAll(routeChecker.getErrors());
+	}
+
+	/**
 	 * 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_SORTING) {
+			return true;
+		}
 		return false;
 	}
@@ -106,5 +159,145 @@
 	@Override
 	public Command fixError(TestError testError) {
-		return null;
+		
+		List<Command> commands = new ArrayList<>(50);
+		
+		if (testError.getCode() == ERROR_CODE_DIRECTION || testError.getCode() == ERROR_CODE_ROAD_TYPE) {
+			commands.add(fixErrorByRemovingWay(testError));
+		}
+		
+		if (testError.getCode() == ERROR_CODE_SORTING) {
+			commands.add(fixSortingError(testError));
+		}
+		
+		if (commands.isEmpty()) {
+			return null;
+		}
+
+		if (commands.size() == 1) {
+			return commands.get(0);
+		}
+
+		return new SequenceCommand(tr("Fix error"), commands);
+	}
+
+
+	private Command fixErrorByRemovingWay(TestError testError) {
+		
+	
+		if (testError.getCode() != ERROR_CODE_ROAD_TYPE && testError.getCode() != ERROR_CODE_DIRECTION) {
+			return null;
+		}
+		
+		List<OsmPrimitive> primitives = (List<OsmPrimitive>) testError.getPrimitives();
+		Relation originalRelation = (Relation) primitives.get(0);
+		List<OsmPrimitive> highlighted = (List<OsmPrimitive>) testError.getHighlighted();
+		Way wayToRemove = (Way) highlighted.get(0);
+
+		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;
+	}
+
+	private Command fixSortingError(TestError testError) {
+		if (testError.getCode() != ERROR_CODE_SORTING) {
+			return null;
+		}
+
+		List<OsmPrimitive> primitives = (List<OsmPrimitive>) testError.getPrimitives();
+		Relation originalRelation = (Relation) primitives.get(0);
+
+		// 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);
+
+		ChangeCommand changeCommand = new ChangeCommand(originalRelation, sortedRelation);
+
+		return changeCommand;
+
 	}
 
