Index: src/org/openstreetmap/josm/corrector/Correction.java
===================================================================
--- src/org/openstreetmap/josm/corrector/Correction.java	(revision 0)
+++ src/org/openstreetmap/josm/corrector/Correction.java	(revision 0)
@@ -0,0 +1,6 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+public interface Correction {
+
+}
Index: src/org/openstreetmap/josm/corrector/CorrectionTable.java
===================================================================
--- src/org/openstreetmap/josm/corrector/CorrectionTable.java	(revision 0)
+++ src/org/openstreetmap/josm/corrector/CorrectionTable.java	(revision 0)
@@ -0,0 +1,62 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Font;
+
+import javax.swing.JLabel;
+import javax.swing.JTable;
+import javax.swing.table.TableCellRenderer;
+
+public abstract class CorrectionTable<TM extends CorrectionTableModel<?>>
+        extends JTable {
+
+	private static final int MAX_VISIBLE_LINES = 10;
+
+    public static class BoldRenderer extends JLabel implements
+	        TableCellRenderer {
+
+		public Component getTableCellRendererComponent(JTable table,
+		        Object value, boolean isSelected, boolean hasFocus, int row,
+		        int column) {
+
+			Font f = getFont();
+			setFont(new Font(f.getName(), f.getStyle() | Font.BOLD, f.getSize()));
+
+			setText((String)value);
+
+			return this;
+		}
+	}
+
+	private static BoldRenderer boldRenderer = null;
+
+	protected CorrectionTable(TM correctionTableModel) {
+		super(correctionTableModel);
+
+		final int correctionsSize = correctionTableModel.getCorrections().size();
+		final int lines = correctionsSize > MAX_VISIBLE_LINES ? MAX_VISIBLE_LINES
+                : correctionsSize;
+		setPreferredScrollableViewportSize(new Dimension(400, lines
+		        * getRowHeight()));
+		getColumnModel().getColumn(correctionTableModel.getApplyColumn())
+                .setPreferredWidth(40);
+		setRowSelectionAllowed(false);
+	}
+
+	public TableCellRenderer getCellRenderer(int row, int column) {
+		if (getCorrectionTableModel().isBoldCell(row, column)) {
+			if (boldRenderer == null)
+				boldRenderer = new BoldRenderer();
+			return boldRenderer;
+		}
+		return super.getCellRenderer(row, column);
+	}
+
+	@SuppressWarnings("unchecked")
+    public TM getCorrectionTableModel() {
+		return (TM)getModel();
+	}
+
+}
\ No newline at end of file
Index: src/org/openstreetmap/josm/corrector/CorrectionTableModel.java
===================================================================
--- src/org/openstreetmap/josm/corrector/CorrectionTableModel.java	(revision 0)
+++ src/org/openstreetmap/josm/corrector/CorrectionTableModel.java	(revision 0)
@@ -0,0 +1,80 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.swing.table.AbstractTableModel;
+
+public abstract class CorrectionTableModel<C extends Correction> extends
+        AbstractTableModel {
+
+	private List<C> corrections;
+	private boolean[] apply;
+	private int applyColumn;
+
+	public CorrectionTableModel(List<C> corrections) {
+		super();
+		this.corrections = corrections;
+		apply = new boolean[this.corrections.size()];
+		Arrays.fill(apply, true);
+		applyColumn = getColumnCount() - 1; 
+	}
+
+	abstract public int getColumnCount();
+
+	abstract protected boolean isBoldCell(int row, int column);
+	abstract public String getCorrectionColumnName(int colIndex);
+	abstract public Object getCorrectionValueAt(int rowIndex, int colIndex);
+
+	public List<C> getCorrections() {
+		return corrections;
+	}
+	
+	public int getApplyColumn() {
+		return applyColumn;
+	}
+	
+    public boolean getApply(int i) {
+    	return apply[i];
+    }
+
+	public int getRowCount() {
+    	return corrections.size();
+    }
+
+	@Override
+    public Class<?> getColumnClass(int columnIndex) {
+    	if (columnIndex == applyColumn)
+    		return Boolean.class;
+    	return String.class;
+    }
+
+	@Override
+	public String getColumnName(int columnIndex) {
+    	if (columnIndex == applyColumn)
+    		return tr("Apply?");
+		
+		return getCorrectionColumnName(columnIndex);
+	}
+
+	@Override
+    public boolean isCellEditable(int rowIndex, int columnIndex) {
+    	return columnIndex == applyColumn;
+    }
+
+	@Override
+    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
+    	if (columnIndex == applyColumn && aValue instanceof Boolean)
+    		apply[rowIndex] = (Boolean)aValue;
+    }
+
+    public Object getValueAt(int rowIndex, int colIndex) {
+    	if (colIndex == applyColumn)
+    		return apply[rowIndex];
+    	
+    	return getCorrectionValueAt(rowIndex, colIndex);
+	}
+}
\ No newline at end of file
Index: src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java
===================================================================
--- src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java	(revision 996)
+++ src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java	(working copy)
@@ -11,9 +11,12 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import org.openstreetmap.josm.command.ChangePropertyCommand;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.Command;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 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;
 
 public class ReverseWayTagCorrector extends TagCorrector<Way> {
@@ -21,52 +24,58 @@
 	private static class PrefixSuffixSwitcher {
 
 		private final String a;
-
 		private final String b;
-
 		private final Pattern startPattern;
-
 		private final Pattern endPattern;
 
+		private final String SEPARATOR = "[:_]?";
+		
 		public PrefixSuffixSwitcher(String a, String b) {
-			this.a = a;
-			this.b = b;
-			startPattern = Pattern.compile("^(" + a + "|" + b + "):.*",
-			        Pattern.CASE_INSENSITIVE);
-			endPattern = Pattern.compile(".*:(" + a + "|" + b + ")$",
-			        Pattern.CASE_INSENSITIVE);
+            this.a = a;
+            this.b = b;
+            startPattern = Pattern.compile(
+                    "^(" + a + "|" + b + ")" + SEPARATOR,
+                    Pattern.CASE_INSENSITIVE);
+            endPattern = Pattern.compile(
+                    SEPARATOR + "(" + a + "|" + b + ")$",
+                    Pattern.CASE_INSENSITIVE);
 		}
 
 		public String apply(String text) {
 			Matcher m = startPattern.matcher(text);
-			if (!m.matches())
+			if (!m.lookingAt())
 				m = endPattern.matcher(text);
 
-			if (m.matches()) {
+			if (m.lookingAt()) {
 				String leftRight = m.group(1).toLowerCase();
 
-				return text.substring(0, m.start(1)).concat(
-				        leftRight.equals(a) ? b : a).concat(
-				        text.substring(m.end(1)));
+				StringBuilder result = new StringBuilder();
+				result.append(text.substring(0, m.start(1)));
+				result.append(leftRight.equals(a) ? b : a);
+				result.append(text.substring(m.end(1)));
+				
+				return result.toString();
 			}
 			return text;
 		}
 	}
 
-	private static PrefixSuffixSwitcher[] prefixSuffixSwitchers = new PrefixSuffixSwitcher[] {
-	        new PrefixSuffixSwitcher("left", "right"),
-	        new PrefixSuffixSwitcher("forward", "backward") };
+	private static PrefixSuffixSwitcher[] prefixSuffixSwitchers = 
+	        new PrefixSuffixSwitcher[] {
+	            new PrefixSuffixSwitcher("left", "right"),
+	            new PrefixSuffixSwitcher("forward", "backward") 
+	        };
 
-	@Override public Collection<ChangePropertyCommand> execute(Way way) {
+	@Override
+	public Collection<Command> execute(Way way) throws UserCancelException {
+		Map<OsmPrimitive, List<TagCorrection>> tagCorrectionsMap = 
+		        new HashMap<OsmPrimitive, List<TagCorrection>>();
 
-		Map<OsmPrimitive, List<TagCorrection>> tagCorrectionsMap = new HashMap<OsmPrimitive, List<TagCorrection>>();
-
 		ArrayList<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>();
 		primitives.add(way);
 		primitives.addAll(way.nodes);
 
 		for (OsmPrimitive primitive : primitives) {
-
 			tagCorrectionsMap.put(primitive, new ArrayList<TagCorrection>());
 
 			for (String key : primitive.keySet()) {
@@ -97,7 +106,33 @@
 			}
 		}
 
-		return applyCorrections(tagCorrectionsMap,
+		Map<OsmPrimitive, List<RoleCorrection>> roleCorrectionMap = 
+		        new HashMap<OsmPrimitive, List<RoleCorrection>>();
+		roleCorrectionMap.put(way, new ArrayList<RoleCorrection>());
+
+		for (Relation relation : Main.ds.relations) {
+			for (RelationMember member : relation.members) {
+				if (!member.member.realEqual(way, true)
+				        || member.role.isEmpty())
+					continue;
+
+				boolean found = false;
+				String newRole = null;
+				for (PrefixSuffixSwitcher prefixSuffixSwitcher : prefixSuffixSwitchers) {
+					newRole = prefixSuffixSwitcher.apply(member.role);
+					if (!newRole.equals(member.role)) {
+						found = true;
+						break;
+					}
+				}
+
+				if (found)
+					roleCorrectionMap.get(way).add(
+					        new RoleCorrection(relation, member, newRole));
+			}
+		}
+
+		return applyCorrections(tagCorrectionsMap, roleCorrectionMap,
 		        tr("When reverting this way, following changes to properties "
 		                + "of the way and its nodes are suggested in order "
 		                + "to maintain data consistency."));
Index: src/org/openstreetmap/josm/corrector/RoleCorrection.java
===================================================================
--- src/org/openstreetmap/josm/corrector/RoleCorrection.java	(revision 0)
+++ src/org/openstreetmap/josm/corrector/RoleCorrection.java	(revision 0)
@@ -0,0 +1,19 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
+
+public class RoleCorrection implements Correction {
+
+    public final Relation relation;
+    public final RelationMember member;
+    public final String newRole;
+
+    public RoleCorrection(Relation relation, RelationMember member,
+            String newRole) {
+        this.relation = relation;
+        this.member = member;
+        this.newRole = newRole;
+    }
+}
Index: src/org/openstreetmap/josm/corrector/RoleCorrectionTable.java
===================================================================
--- src/org/openstreetmap/josm/corrector/RoleCorrectionTable.java	(revision 0)
+++ src/org/openstreetmap/josm/corrector/RoleCorrectionTable.java	(revision 0)
@@ -0,0 +1,13 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+import java.util.List;
+
+public class RoleCorrectionTable extends
+        CorrectionTable<RoleCorrectionTableModel> {
+
+    public RoleCorrectionTable(List<RoleCorrection> roleCorrections) {
+        super(new RoleCorrectionTableModel(roleCorrections));
+    }
+
+}
Index: src/org/openstreetmap/josm/corrector/RoleCorrectionTableModel.java
===================================================================
--- src/org/openstreetmap/josm/corrector/RoleCorrectionTableModel.java	(revision 0)
+++ src/org/openstreetmap/josm/corrector/RoleCorrectionTableModel.java	(revision 0)
@@ -0,0 +1,58 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.List;
+
+import org.openstreetmap.josm.data.osm.visitor.NameVisitor;
+
+public class RoleCorrectionTableModel extends
+        CorrectionTableModel<RoleCorrection> {
+
+    private static NameVisitor nameVisitor = new NameVisitor();
+
+    public RoleCorrectionTableModel(List<RoleCorrection> roleCorrections) {
+        super(roleCorrections);
+    }
+
+    @Override
+    public int getColumnCount() {
+        return 4;
+    }
+
+    @Override
+    public String getCorrectionColumnName(int colIndex) {
+        switch (colIndex) {
+        case 0:
+            return tr("Relation");
+        case 1:
+            return tr("Old role");
+        case 2:
+            return tr("New role");
+        }
+        return null;
+    }
+
+    @Override
+    public Object getCorrectionValueAt(int rowIndex, int colIndex) {
+        RoleCorrection roleCorrection = getCorrections().get(rowIndex);
+
+        switch (colIndex) {
+        case 0:
+            roleCorrection.relation.visit(nameVisitor);
+            return nameVisitor.name;
+        case 1:
+            return roleCorrection.member.role;
+        case 2:
+            return roleCorrection.newRole;
+        }
+        return null;
+    }
+
+    @Override
+    protected boolean isBoldCell(int row, int column) {
+        return column == 2;
+    }
+
+}
Index: src/org/openstreetmap/josm/corrector/TagCorrection.java
===================================================================
--- src/org/openstreetmap/josm/corrector/TagCorrection.java	(revision 996)
+++ src/org/openstreetmap/josm/corrector/TagCorrection.java	(working copy)
@@ -1,14 +1,15 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.corrector;
 
-public class TagCorrection {
+public class TagCorrection implements Correction {
 
 	public final String oldKey;
 	public final String newKey;
 	public final String oldValue;
 	public final String newValue;
 
-	public TagCorrection(String oldKey, String oldValue, String newKey, String newValue) {
+	public TagCorrection(String oldKey, String oldValue, String newKey,
+            String newValue) {
 		this.oldKey = oldKey;
 		this.oldValue = oldValue;
 		this.newKey = newKey;
Index: src/org/openstreetmap/josm/corrector/TagCorrectionTable.java
===================================================================
--- src/org/openstreetmap/josm/corrector/TagCorrectionTable.java	(revision 996)
+++ src/org/openstreetmap/josm/corrector/TagCorrectionTable.java	(working copy)
@@ -1,64 +1,13 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.corrector;
 
-import java.awt.Dimension;
 import java.util.List;
 
-import javax.swing.JTable;
-import javax.swing.JLabel;
-import javax.swing.table.TableCellRenderer;
-import java.awt.Component;
-import java.awt.Font;
+public class TagCorrectionTable extends
+        CorrectionTable<TagCorrectionTableModel> {
 
-public class TagCorrectionTable extends JTable {
-
-	public static class BoldRenderer extends JLabel implements TableCellRenderer {
-
-		public Component getTableCellRendererComponent(JTable table,
-		        Object value, boolean isSelected, boolean hasFocus, int row,
-		        int column) {
-
-			Font f = getFont();
-			setFont(new Font(f.getName(), f.getStyle() | Font.BOLD, f.getSize()));
-
-			setText((String)value);
-
-			return this;
-		}
+	public TagCorrectionTable(List<TagCorrection> tagCorrections) {
+		super(new TagCorrectionTableModel(tagCorrections));
 	}
 
-	private static TableCellRenderer boldRenderer = null;
-
-	public static TagCorrectionTable create(List<TagCorrection> tagCorrections) {
-		TagCorrectionTableModel tagCorrectionTableModel = new TagCorrectionTableModel(tagCorrections);
-		TagCorrectionTable table = new TagCorrectionTable(
-		        tagCorrectionTableModel);
-		int lines = tagCorrections.size() > 10 ? 10 : tagCorrections.size();  
-		table.setPreferredScrollableViewportSize(new Dimension(400, lines * table.getRowHeight()));
-		table.getColumnModel().getColumn(4).setPreferredWidth(40);
-		table.setRowSelectionAllowed(false);
-
-		return table;
-	}
-
-	public TableCellRenderer getCellRenderer(int row, int column) {
-		TagCorrection tagCorrection = getTagCorrectionTableModel().tagCorrections
-		        .get(row);
-		if ((column == 2 && tagCorrection.isKeyChanged())
-		        || (column == 3 && tagCorrection.isValueChanged())) {
-			if (boldRenderer == null)
-				boldRenderer = new BoldRenderer();
-			return boldRenderer;
-		}
-		return super.getCellRenderer(row, column);
-	}
-
-	private TagCorrectionTable(TagCorrectionTableModel tagCorrectionTableModel) {
-		super(tagCorrectionTableModel);
-	}
-
-	public TagCorrectionTableModel getTagCorrectionTableModel() {
-		return (TagCorrectionTableModel) getModel();
-	}
-
 }
Index: src/org/openstreetmap/josm/corrector/TagCorrectionTableModel.java
===================================================================
--- src/org/openstreetmap/josm/corrector/TagCorrectionTableModel.java	(revision 996)
+++ src/org/openstreetmap/josm/corrector/TagCorrectionTableModel.java	(working copy)
@@ -3,34 +3,21 @@
 
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import java.util.Arrays;
 import java.util.List;
 
-import javax.swing.table.AbstractTableModel;
+public class TagCorrectionTableModel extends CorrectionTableModel<TagCorrection> {
 
-public class TagCorrectionTableModel extends AbstractTableModel {
-
-	List<TagCorrection> tagCorrections;
-
-	private boolean[] apply;
-
 	public TagCorrectionTableModel(List<TagCorrection> tagCorrections) {
-		this.tagCorrections = tagCorrections;
-		apply = new boolean[this.tagCorrections.size()];
-		Arrays.fill(apply, true);
+		super(tagCorrections);
 	}
 
+	@Override
 	public int getColumnCount() {
 		return 5;
 	}
 
-	@Override public Class<?> getColumnClass(int columnIndex) {
-		if (columnIndex == 4)
-			return Boolean.class;
-		return String.class;
-	}
-
-	@Override public String getColumnName(int colIndex) {
+	@Override
+	public String getCorrectionColumnName(int colIndex) {
 		switch (colIndex) {
 		case 0:
 			return tr("Old key");
@@ -40,20 +27,13 @@
 			return tr("New key");
 		case 3:
 			return tr("New value");
-		case 4:
-			return tr("Apply?");
 		}
 		return null;
 	}
 
-	public int getRowCount() {
-		return tagCorrections.size();
-	}
+    public Object getCorrectionValueAt(int rowIndex, int colIndex) {
+		TagCorrection tagCorrection = getCorrections().get(rowIndex);
 
-	public Object getValueAt(int rowIndex, int colIndex) {
-
-		TagCorrection tagCorrection = tagCorrections.get(rowIndex);
-
 		switch (colIndex) {
 		case 0:
 			return tagCorrection.oldKey;
@@ -63,23 +43,14 @@
 			return tagCorrection.newKey;
 		case 3:
 			return tagCorrection.newValue;
-		case 4:
-			return apply[rowIndex];
 		}
 		return null;
 	}
 
-	@Override public boolean isCellEditable(int rowIndex, int columnIndex) {
-		return columnIndex == 4;
+	protected boolean isBoldCell(int row, int column) {
+		TagCorrection tagCorrection = getCorrections().get(row);
+		return (column == 2 && tagCorrection.isKeyChanged())
+		        || (column == 3 && tagCorrection.isValueChanged());
 	}
 
-	@Override public void setValueAt(Object aValue, int rowIndex,
-	        int columnIndex) {
-		if (columnIndex == 4 && aValue instanceof Boolean)
-			apply[rowIndex] = (Boolean)aValue;
-	}
-
-	public boolean getApply(int i) {
-		return apply[i];
-	}
 }
Index: src/org/openstreetmap/josm/corrector/TagCorrector.java
===================================================================
--- src/org/openstreetmap/josm/corrector/TagCorrector.java	(revision 996)
+++ src/org/openstreetmap/josm/corrector/TagCorrector.java	(working copy)
@@ -17,19 +17,31 @@
 import javax.swing.JScrollPane;
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.ChangeCommand;
 import org.openstreetmap.josm.command.ChangePropertyCommand;
+import org.openstreetmap.josm.command.Command;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
 import org.openstreetmap.josm.data.osm.visitor.NameVisitor;
 import org.openstreetmap.josm.gui.JMultilineLabel;
 import org.openstreetmap.josm.tools.GBC;
 
 public abstract class TagCorrector<P extends OsmPrimitive> {
 
-	public abstract Collection<ChangePropertyCommand> execute(P primitive);
+	public abstract Collection<Command> execute(P primitive) 
+	    throws UserCancelException;
 
-	protected Collection<ChangePropertyCommand> applyCorrections(
+    private String[] applicationOptions = new String[] { 
+        tr("Apply selected changes"), 
+        tr("Don't apply changes"), 
+        tr("Cancel") 
+    };
+    
+	protected Collection<Command> applyCorrections(
 	        Map<OsmPrimitive, List<TagCorrection>> tagCorrectionsMap,
-	        String description) {
+	        Map<OsmPrimitive, List<RoleCorrection>> roleCorrectionMap,
+	        String description) throws UserCancelException {
 
 		boolean hasCorrections = false;
 		for (List<TagCorrection> tagCorrectionList : tagCorrectionsMap.values()) {
@@ -39,9 +51,22 @@
 			}
 		}
 
+		if (!hasCorrections)
+			for (List<RoleCorrection> roleCorrectionList : roleCorrectionMap
+			        .values()) {
+				if (!roleCorrectionList.isEmpty()) {
+					hasCorrections = true;
+					break;
+				}
+			}
+
 		if (hasCorrections) {
-			Collection<ChangePropertyCommand> changePropertyCommands = new ArrayList<ChangePropertyCommand>();
-			Map<OsmPrimitive, TagCorrectionTable> tableMap = new HashMap<OsmPrimitive, TagCorrectionTable>();
+			Collection<Command> commands = new ArrayList<Command>();
+			Map<OsmPrimitive, TagCorrectionTable> tagTableMap = 
+			    new HashMap<OsmPrimitive, TagCorrectionTable>();
+			Map<OsmPrimitive, RoleCorrectionTable> roleTableMap = 
+			    new HashMap<OsmPrimitive, RoleCorrectionTable>();
+
 			NameVisitor nameVisitor = new NameVisitor();
 
 			final JPanel p = new JPanel(new GridBagLayout());
@@ -62,46 +87,91 @@
 				if (tagCorrections.isEmpty())
 					continue;
 
-				final TagCorrectionTable table = TagCorrectionTable
-				        .create(tagCorrections);
+				primitive.visit(nameVisitor);
+
+				final JLabel propertiesLabel = new JLabel(tr("Properties of "));
+				p.add(propertiesLabel, GBC.std());
+
+				final JLabel primitiveLabel = new JLabel(
+				        nameVisitor.name + ":", nameVisitor.icon, JLabel.LEFT);
+				p.add(primitiveLabel, GBC.eol());
+
+				final TagCorrectionTable table = new TagCorrectionTable(
+				        tagCorrections);
 				final JScrollPane scrollPane = new JScrollPane(table);
-				tableMap.put(primitive, table);
+				p.add(scrollPane, GBC.eop());
 
+				tagTableMap.put(primitive, table);
+			}
+
+			for (OsmPrimitive primitive : roleCorrectionMap.keySet()) {
+				final List<RoleCorrection> roleCorrections = roleCorrectionMap
+				        .get(primitive);
+				if (roleCorrections.isEmpty())
+					continue;
+
 				primitive.visit(nameVisitor);
 
-				final JLabel label3 = new JLabel(nameVisitor.name + ":",
-				        nameVisitor.icon, JLabel.LEFT);
+				final JLabel rolesLabel = new JLabel(
+				        tr("Roles in relations refering to"));
+				p.add(rolesLabel, GBC.std());
 
-				p.add(label3, GBC.eol());
+				final JLabel primitiveLabel = new JLabel(
+				        nameVisitor.name + ":", nameVisitor.icon, JLabel.LEFT);
+				p.add(primitiveLabel, GBC.eol());
+
+				final RoleCorrectionTable table = new RoleCorrectionTable(
+				        roleCorrections);
+				final JScrollPane scrollPane = new JScrollPane(table);
 				p.add(scrollPane, GBC.eop());
+
+				roleTableMap.put(primitive, table);
 			}
 
-			int answer = JOptionPane.showConfirmDialog(Main.parent, p,
-			        tr("Automatic tag correction"),
-			        JOptionPane.OK_CANCEL_OPTION);
+			int answer = JOptionPane.showOptionDialog(Main.parent, p,
+                    tr("Automatic tag correction"), JOptionPane.YES_NO_CANCEL_OPTION,
+                    JOptionPane.PLAIN_MESSAGE, null, 
+                    applicationOptions, applicationOptions[0]);
 
-			if (answer == JOptionPane.OK_OPTION) {
+			if (answer == JOptionPane.YES_OPTION) {
 				for (OsmPrimitive primitive : tagCorrectionsMap.keySet()) {
 					List<TagCorrection> tagCorrections = tagCorrectionsMap
 					        .get(primitive);
 					for (int i = 0; i < tagCorrections.size(); i++) {
-						if (tableMap.get(primitive)
-						        .getTagCorrectionTableModel().getApply(i)) {
+						if (tagTableMap.get(primitive)
+						        .getCorrectionTableModel().getApply(i)) {
 							TagCorrection tagCorrection = tagCorrections.get(i);
 							if (tagCorrection.isKeyChanged())
-								changePropertyCommands
-								        .add(new ChangePropertyCommand(
-								                primitive,
-								                tagCorrection.oldKey, null));
-							changePropertyCommands
-							        .add(new ChangePropertyCommand(primitive,
-							                tagCorrection.newKey,
-							                tagCorrection.newValue));
+								commands.add(new ChangePropertyCommand(
+								        primitive, tagCorrection.oldKey, null));
+							commands.add(new ChangePropertyCommand(primitive,
+							        tagCorrection.newKey,
+							        tagCorrection.newValue));
 						}
 					}
 				}
+				for (OsmPrimitive primitive : roleCorrectionMap.keySet()) {
+					List<RoleCorrection> roleCorrections = roleCorrectionMap
+					        .get(primitive);
+					for (int i = 0; i < roleCorrections.size(); i++) {
+						if (roleTableMap.get(primitive)
+						        .getCorrectionTableModel().getApply(i)) {
+							RoleCorrection roleCorrection = roleCorrections
+							        .get(i);
+							Relation newRelation = new Relation(
+							        roleCorrection.relation);
+							for (RelationMember member : newRelation.members)
+								if (member.equals(roleCorrection.member))
+									member.role = roleCorrection.newRole;
+							commands.add(new ChangeCommand(
+							        roleCorrection.relation, newRelation));
+						}
+					}
+				}
+			} else if (answer != JOptionPane.NO_OPTION) {
+			    throw new UserCancelException();
 			}
-			return changePropertyCommands;
+			return commands;
 		}
 
 		return Collections.emptyList();
Index: src/org/openstreetmap/josm/corrector/UserCancelException.java
===================================================================
--- src/org/openstreetmap/josm/corrector/UserCancelException.java	(revision 0)
+++ src/org/openstreetmap/josm/corrector/UserCancelException.java	(revision 0)
@@ -0,0 +1,6 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+public class UserCancelException extends Exception {
+
+}
