Index: trunk/src/org/openstreetmap/josm/actions/ReverseWayAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/ReverseWayAction.java	(revision 728)
+++ trunk/src/org/openstreetmap/josm/actions/ReverseWayAction.java	(revision 729)
@@ -16,4 +16,5 @@
 import org.openstreetmap.josm.command.Command;
 import org.openstreetmap.josm.command.SequenceCommand;
+import org.openstreetmap.josm.corrector.ReverseWayTagCorrector;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.Node;
@@ -47,12 +48,19 @@
     		return;
     	}
-    	Collection<Command> c = new LinkedList<Command>();
-    	for (Way w : sel) {
-    		Way wnew = new Way(w);
+
+    	boolean propertiesUpdated = false;
+		ReverseWayTagCorrector reverseWayTagCorrector = new ReverseWayTagCorrector();
+		Collection<Command> c = new LinkedList<Command>();
+		for (Way w : sel) {
+			Way wnew = new Way(w);
 			Collections.reverse(wnew.nodes);
-    		c.add(new ChangeCommand(w, wnew));
-    	}
-    	Main.main.undoRedo.add(new SequenceCommand(tr("Reverse ways"), c));
-    	Main.map.repaint();
+			if (Main.pref.getBoolean("tag-correction.reverse-way", true))
+				propertiesUpdated = reverseWayTagCorrector.execute(wnew) || propertiesUpdated;
+			c.add(new ChangeCommand(w, wnew));
+		}
+		Main.main.undoRedo.add(new SequenceCommand(tr("Reverse ways"), c));
+		if (propertiesUpdated)
+			Main.map.getPropertiesDialog().selectionChanged(Main.ds.getSelected());
+		Main.map.repaint();
     }
 }
Index: trunk/src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java
===================================================================
--- trunk/src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java	(revision 729)
+++ trunk/src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java	(revision 729)
@@ -0,0 +1,63 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.openstreetmap.josm.data.osm.OsmUtils;
+import org.openstreetmap.josm.data.osm.Way;
+
+public class ReverseWayTagCorrector extends TagCorrector<Way> {
+
+	private static final Pattern leftRightStartRegex = Pattern.compile(
+	        "^(left|right):.*", Pattern.CASE_INSENSITIVE);
+
+	private static final Pattern leftRightEndRegex = Pattern.compile(
+	        ".*:(left|right)$", Pattern.CASE_INSENSITIVE);
+
+	@Override public boolean execute(Way way) {
+
+		ArrayList<TagCorrection> tagCorrections = new ArrayList<TagCorrection>();
+
+		for (String key : way.keySet()) {
+			String newKey = key;
+			String value = way.get(key);
+			String newValue = value;
+
+			if (key.equals("oneway")) {
+				if (value.equals("-1"))
+					newValue = OsmUtils.trueval;
+				else {
+					Boolean boolValue = OsmUtils.getOsmBoolean(value);
+					if (boolValue != null && boolValue.booleanValue()) {
+						newValue = "-1";
+					}
+				}
+			} else {
+				Matcher m = leftRightStartRegex.matcher(key);
+				if (!m.matches())
+					m = leftRightEndRegex.matcher(key);
+
+				if (m.matches()) {
+					String leftRight = m.group(1).toLowerCase();
+
+					newKey = key.substring(0, m.start(1)).concat(
+					        leftRight.equals("left") ? "right" : "left")
+					        .concat(key.substring(m.end(1)));
+				}
+			}
+
+			if (key != newKey || value != newValue)
+				tagCorrections.add(new TagCorrection(key, value, newKey,
+				        newValue));
+		}
+
+		return applyCorrections(tagCorrections, way,
+		        tr("When reverting this way, following changes to the "
+		                + "properties are suggested in order to maintain "
+		                + "data consistency."));
+	}
+}
Index: trunk/src/org/openstreetmap/josm/corrector/TagCorrection.java
===================================================================
--- trunk/src/org/openstreetmap/josm/corrector/TagCorrection.java	(revision 729)
+++ trunk/src/org/openstreetmap/josm/corrector/TagCorrection.java	(revision 729)
@@ -0,0 +1,25 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+public class TagCorrection {
+
+	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) {
+		this.oldKey = oldKey;
+		this.oldValue = oldValue;
+		this.newKey = newKey;
+		this.newValue = newValue;
+	}
+
+	public boolean isKeyChanged() {
+		return !newKey.equals(oldKey);
+	}
+
+	public boolean isValueChanged() {
+		return !newValue.equals(oldValue);
+	}
+}
Index: trunk/src/org/openstreetmap/josm/corrector/TagCorrectionTable.java
===================================================================
--- trunk/src/org/openstreetmap/josm/corrector/TagCorrectionTable.java	(revision 729)
+++ trunk/src/org/openstreetmap/josm/corrector/TagCorrectionTable.java	(revision 729)
@@ -0,0 +1,67 @@
+// 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 JTable {
+
+	public 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 TableCellRenderer boldRenderer = null;
+
+	private static TagCorrectionTableModel tagCorrectionTableModel;
+
+	public static TagCorrectionTable create(List<TagCorrection> tagCorrections) {
+
+		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 = tagCorrectionTableModel.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;
+	}
+
+}
Index: trunk/src/org/openstreetmap/josm/corrector/TagCorrectionTableModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/corrector/TagCorrectionTableModel.java	(revision 729)
+++ trunk/src/org/openstreetmap/josm/corrector/TagCorrectionTableModel.java	(revision 729)
@@ -0,0 +1,85 @@
+// 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 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);
+	}
+
+	@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) {
+		switch (colIndex) {
+		case 0:
+			return tr("Old key");
+		case 1:
+			return tr("Old value");
+		case 2:
+			return tr("New key");
+		case 3:
+			return tr("New value");
+		case 4:
+			return tr("Apply?");
+		}
+		return null;
+	}
+
+	@Override public int getRowCount() {
+		return tagCorrections.size();
+	}
+
+	@Override public Object getValueAt(int rowIndex, int colIndex) {
+
+		TagCorrection tagCorrection = tagCorrections.get(rowIndex);
+
+		switch (colIndex) {
+		case 0:
+			return tagCorrection.oldKey;
+		case 1:
+			return tagCorrection.oldValue;
+		case 2:
+			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;
+	}
+
+	@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: trunk/src/org/openstreetmap/josm/corrector/TagCorrector.java
===================================================================
--- trunk/src/org/openstreetmap/josm/corrector/TagCorrector.java	(revision 729)
+++ trunk/src/org/openstreetmap/josm/corrector/TagCorrector.java	(revision 729)
@@ -0,0 +1,67 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.Dimension;
+import java.awt.GridBagLayout;
+import java.util.List;
+
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.gui.JMultilineLabel;
+import org.openstreetmap.josm.tools.GBC;
+
+public abstract class TagCorrector<P extends OsmPrimitive> {
+
+	public abstract boolean execute(P primitive);
+
+	protected boolean applyCorrections(List<TagCorrection> tagCorrections,
+	        P primitive, String description) {
+
+		boolean updated = false;
+
+		if (tagCorrections != null && tagCorrections.size() > 0) {
+
+			final TagCorrectionTable table = TagCorrectionTable
+			        .create(tagCorrections);
+			final JScrollPane scrollPane = new JScrollPane(table);
+
+	    	final JPanel p = new JPanel(new GridBagLayout());
+
+			final JMultilineLabel label1 = new JMultilineLabel(description);
+			label1.setMaxWidth(400);
+			p.add(label1, GBC.eop());
+			
+			final JMultilineLabel label2 = new JMultilineLabel(tr("Please select which property changes you want to apply."));
+			label2.setMaxWidth(400);
+			p.add(label2, GBC.eop());
+	    	p.add(scrollPane, GBC.eol());
+			
+			int answer = JOptionPane.showConfirmDialog(Main.parent, p,
+			        tr("Automatic tag correction"),
+			        JOptionPane.OK_CANCEL_OPTION);
+
+			if (answer == JOptionPane.OK_OPTION) {
+				for (int i = 0; i < tagCorrections.size(); i++) {
+					if (table.getTagCorrectionTableModel().getApply(i)) {
+						TagCorrection tagCorrection = tagCorrections.get(i);
+						if (tagCorrection.isKeyChanged())
+							primitive.remove(tagCorrection.oldKey);
+						primitive.put(tagCorrection.newKey, tagCorrection
+						        .newValue);
+						updated = true;
+					}
+				}
+			}
+		}
+
+		return updated;
+	}
+
+}
Index: trunk/src/org/openstreetmap/josm/gui/JMultilineLabel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/JMultilineLabel.java	(revision 729)
+++ trunk/src/org/openstreetmap/josm/gui/JMultilineLabel.java	(revision 729)
@@ -0,0 +1,114 @@
+// License: GPL. For details, see LICENSE file.
+
+// This class was taken from 
+// http://forum.java.sun.com/thread.jspa?threadID=459705&messageID=2104021
+// - Removed hardcoded margin
+// -  Added constructor
+
+package org.openstreetmap.josm.gui;
+
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Insets;
+import java.awt.font.FontRenderContext;
+import java.awt.font.LineBreakMeasurer;
+import java.awt.font.TextAttribute;
+import java.text.AttributedCharacterIterator;
+import java.text.AttributedString;
+import java.awt.font.TextLayout;
+
+import javax.swing.JComponent;
+
+public class JMultilineLabel extends JComponent {
+	private String text;
+	private int maxWidth = Integer.MAX_VALUE;
+	private boolean justify;
+	private final FontRenderContext frc = new FontRenderContext(null, false, false);
+
+	public JMultilineLabel(String description) {
+		super();
+		setText(description);
+	}
+
+	private void morph() {
+		revalidate();
+		repaint();
+	}
+
+	public String getText() {
+		return text;
+	}
+
+	public void setText(String text) {
+		String old = this.text;
+		this.text = text;
+		firePropertyChange("text", old, this.text);
+		if ((old == null) ? text!=null : !old.equals(text))
+			morph();
+	}
+
+	public int getMaxWidth() {
+		return maxWidth;
+	}
+
+	public void setMaxWidth(int maxWidth) {
+		if (maxWidth <= 0)
+			throw new IllegalArgumentException();
+		int old = this.maxWidth;
+		this.maxWidth = maxWidth;
+		firePropertyChange("maxWidth", old, this.maxWidth);
+		if (old !=	this.maxWidth)
+			morph();
+	}
+
+	public boolean isJustified() {
+		return justify;
+	}
+
+	public void setJustified(boolean justify) {
+		boolean old = this.justify;
+		this.justify = justify;
+		firePropertyChange("justified", old, this.justify);
+		if (old != this.justify)
+			repaint();
+	}
+
+	public Dimension getPreferredSize() {
+		return paintOrGetSize(null, getMaxWidth());
+	}
+
+	public Dimension getMinimumSize() {
+		return getPreferredSize();
+	}
+
+	protected void paintComponent(Graphics g) {
+		super.paintComponent(g);
+		paintOrGetSize((Graphics2D)g, getWidth());
+	}
+
+	private Dimension paintOrGetSize(Graphics2D g, int width) {
+		Insets insets = getInsets();
+		width -= insets.left + insets.right;
+		float w = insets.left + insets.right;
+		float x = insets.left, y=insets.top;
+		if (width > 0 && text != null && text.length() > 0) {
+			AttributedString as = new AttributedString(getText());
+			as.addAttribute(TextAttribute.FONT, getFont());
+			AttributedCharacterIterator aci = as.getIterator();
+			LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc);
+			float max = 0;
+			while (lbm.getPosition() < aci.getEndIndex()) {
+				TextLayout textLayout = lbm.nextLayout(width);
+				if (g != null && isJustified() && textLayout.getVisibleAdvance() > 0.80 * width)
+					textLayout = textLayout.getJustifiedLayout(width);
+				if (g != null)
+					textLayout.draw(g, x, y + textLayout.getAscent());
+				y += textLayout.getDescent() + textLayout.getLeading() + textLayout.getAscent();
+				max = Math.max(max, textLayout.getVisibleAdvance());
+			}
+			w += max;
+		}
+		return new Dimension((int)Math.ceil(w), (int)Math.ceil(y) + insets.bottom);
+	}
+}
Index: trunk/src/org/openstreetmap/josm/gui/MapFrame.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MapFrame.java	(revision 728)
+++ trunk/src/org/openstreetmap/josm/gui/MapFrame.java	(revision 729)
@@ -67,4 +67,5 @@
 	public final ButtonGroup toolGroup = new ButtonGroup();
 
+	private PropertiesDialog propertiesDialog;
 
 	public MapFrame() {
@@ -95,5 +96,5 @@
 
 		addToggleDialog(new LayerListDialog(this));
-		addToggleDialog(new PropertiesDialog(this));
+		addToggleDialog(propertiesDialog = new PropertiesDialog(this));
 		addToggleDialog(new HistoryDialog());
 		addToggleDialog(new SelectionListDialog());
@@ -188,3 +189,7 @@
 			panel.add(statusLine, BorderLayout.SOUTH);
 	}
+
+	public final PropertiesDialog getPropertiesDialog() {
+    	return propertiesDialog;
+    }
 }
