Index: trunk/src/org/openstreetmap/josm/actions/ReverseWayAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/ReverseWayAction.java	(revision 5723)
+++ trunk/src/org/openstreetmap/josm/actions/ReverseWayAction.java	(revision 5724)
@@ -19,4 +19,5 @@
 import org.openstreetmap.josm.command.Command;
 import org.openstreetmap.josm.command.SequenceCommand;
+import org.openstreetmap.josm.corrector.ReverseWayNoTagCorrector;
 import org.openstreetmap.josm.corrector.ReverseWayTagCorrector;
 import org.openstreetmap.josm.corrector.UserCancelException;
@@ -109,6 +110,8 @@
      * @param w the way
      * @return the reverse command and the tag correction commands
+     * @throws UserCancelException if user cancels a reverse warning dialog
      */
     public static ReverseWayResult reverseWay(Way w) throws UserCancelException {
+        ReverseWayNoTagCorrector.checkAndConfirmReverseWay(w);
         Way wnew = new Way(w);
         List<Node> nodesCopy = wnew.getNodes();
Index: trunk/src/org/openstreetmap/josm/corrector/ReverseWayNoTagCorrector.java
===================================================================
--- trunk/src/org/openstreetmap/josm/corrector/ReverseWayNoTagCorrector.java	(revision 5724)
+++ trunk/src/org/openstreetmap/josm/corrector/ReverseWayNoTagCorrector.java	(revision 5724)
@@ -0,0 +1,117 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+import static org.openstreetmap.josm.tools.I18n.trn;
+
+import java.util.Arrays;
+
+import javax.swing.JOptionPane;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.Tag;
+import org.openstreetmap.josm.data.osm.TagCollection;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil;
+import org.openstreetmap.josm.gui.DefaultNameFormatter;
+
+/**
+ * A ReverseWayNoTagCorrector warns about ways that should not be reversed
+ * because their semantic meaning cannot be preserved in that case. 
+ * E.g. natural=coastline, natural=cliff, barrier=retaining_wall cannot be changed.
+ * @see ReverseWayTagCorrector for handling of tags that can be modified (oneway=yes, etc.)
+ * @since 5724
+ */
+public class ReverseWayNoTagCorrector {
+
+    /**
+     * Tags that imply a semantic meaning from the way direction and cannot be changed. 
+     */
+    public static final TagCollection directionalTags = new TagCollection(Arrays.asList(new Tag[]{
+            new Tag("natural", "coastline"),
+            new Tag("natural", "cliff"),
+            new Tag("barrier", "retaining_wall"),
+            new Tag("waterway", "stream"),
+            new Tag("waterway", "river"),
+            new Tag("waterway", "ditch"),
+            new Tag("waterway", "drain"),
+            new Tag("waterway", "canal")
+    }));
+    
+    /**
+     * Replies the tags that imply a semantic meaning from <code>way</code> direction and cannot be changed. 
+     * @param way The way to look for
+     * @return tags that imply a semantic meaning from <code>way</code> direction and cannot be changed
+     */
+    public static final TagCollection getDirectionalTags(Way way) {
+        return directionalTags.intersect(TagCollection.from(way));
+    }
+    
+    /**
+     * Tests whether way can be reversed without semantic change.
+     * Looks for tags like natural=cliff, barrier=retaining_wall.
+     * @param way The way to check
+     * @return false if the semantic meaning change if the way is reversed, true otherwise.
+     */
+    public static boolean isReversible(Way way) {
+        return getDirectionalTags(way).isEmpty();
+    }
+    
+    protected static String getHTML(TagCollection tags) {
+        if (tags.size() == 1) {
+            return tags.iterator().next().toString();
+        } else if (tags.size() > 1) {
+            String s = "<ul>";
+            for (Tag t : tags) {
+                s += "<li>" + t.toString() + "</li>";
+            }
+            s += "</ul>";
+            return s;
+        } else {
+            return "";
+        }
+    }
+    
+    protected static boolean confirmReverseWay(Way way, TagCollection tags) {
+        String msg = trn(
+                // Singular, if a single tag is impacted
+                "<html>You are going to reverse the way ''{0}'',"
+                + "<br/> whose semantic meaning of its tag ''{1}'' is defined by its direction.<br/>"
+                + "Do you really want to change the way direction, thus its semantic meaning?</html>",
+                // Plural, if several tags are impacted
+                "<html>You are going to reverse the way ''{0}'',"
+                + "<br/> whose semantic meaning of these tags are defined by its direction:<br/>{1}"
+                + "Do you really want to change the way direction, thus its semantic meaning?</html>",
+                tags.size(),
+                way.getDisplayName(DefaultNameFormatter.getInstance()),
+                getHTML(tags)
+            );
+        int ret = ConditionalOptionPaneUtil.showOptionDialog(
+                "reverse_directional_way",
+                Main.parent,
+                msg,
+                tr("Reverse directional way."),
+                JOptionPane.YES_NO_CANCEL_OPTION,
+                JOptionPane.WARNING_MESSAGE,
+                null,
+                null
+        );
+        switch(ret) {
+            case ConditionalOptionPaneUtil.DIALOG_DISABLED_OPTION : return true;
+            case JOptionPane.YES_OPTION: return true;
+            default: return false;
+        }
+    }
+    
+    /**
+     * Checks the given way can be safely reversed and asks user to confirm the operation if it not the case.
+     * @param way The way to check
+     * @throws UserCancelException If the user cancels the operation
+     */
+    public static void checkAndConfirmReverseWay(Way way) throws UserCancelException {
+        TagCollection tags = getDirectionalTags(way);
+        if (!tags.isEmpty() && !confirmReverseWay(way, tags)) {
+            throw new UserCancelException();
+        }
+    }
+}
Index: trunk/src/org/openstreetmap/josm/data/osm/TagCollection.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/TagCollection.java	(revision 5723)
+++ trunk/src/org/openstreetmap/josm/data/osm/TagCollection.java	(revision 5724)
@@ -24,5 +24,5 @@
  * A TagCollection can be created:
  * <ul>
- *  <li>from the tags managed by a specific {@link OsmPrimitive} with {@link #from(OsmPrimitive)}</li>
+ *  <li>from the tags managed by a specific {@link OsmPrimitive} with {@link #from(Tagged)}</li>
  *  <li>from the union of all tags managed by a collection of {@link OsmPrimitive}s with {@link #unionOfAllPrimitives(Collection)}</li>
  *  <li>from the union of all tags managed by a {@link DataSet} with {@link #unionOfAllPrimitives(DataSet)}</li>
@@ -51,6 +51,8 @@
     public static TagCollection from(Tagged primitive) {
         TagCollection tags = new TagCollection();
-        for (String key: primitive.keySet()) {
-            tags.add(new Tag(key, primitive.get(key)));
+        if (primitive != null) {
+            for (String key: primitive.keySet()) {
+                tags.add(new Tag(key, primitive.get(key)));
+            }
         }
         return tags;
@@ -158,4 +160,13 @@
 
     /**
+     * Creates a tag collection from <code>tags</code>.
+     * @param tags the collection of tags
+     * @since 5724
+     */
+    public TagCollection(Collection<Tag> tags) {
+        add(tags);
+    }
+
+    /**
      * Replies the number of tags in this tag collection
      *
@@ -637,5 +648,5 @@
      * Does nothing if primitives is null
      *
-     * @param primitive  the collection of primitives
+     * @param primitives the collection of primitives
      * @throws IllegalStateException thrown if this tag collection can't be applied
      * because there are keys with multiple values
@@ -657,11 +668,10 @@
      */
     public TagCollection intersect(TagCollection other) {
-        if (other == null) {
-            other = new TagCollection();
-        }
-        TagCollection ret = new TagCollection(this);
-        for (Tag tag: tags) {
-            if (other.contains(tag)) {
-                ret.add(tag);
+        TagCollection ret = new TagCollection();
+        if (other != null) {
+            for (Tag tag: tags) {
+                if (other.contains(tag)) {
+                    ret.add(tag);
+                }
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/ConditionalOptionPaneUtil.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/ConditionalOptionPaneUtil.java	(revision 5723)
+++ trunk/src/org/openstreetmap/josm/gui/ConditionalOptionPaneUtil.java	(revision 5724)
@@ -98,5 +98,5 @@
      * @param messageType the message type
      * @param options a list of options
-     * @param defaultOption the default option
+     * @param defaultOption the default option; only meaningful if options is used; can be null
      *
      * @return the option selected by user. {@link JOptionPane#CLOSED_OPTION} if the dialog was closed.
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java	(revision 5723)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java	(revision 5724)
@@ -31,5 +31,19 @@
 import java.util.Set;
 
-import javax.swing.*;
+import javax.swing.AbstractAction;
+import javax.swing.BorderFactory;
+import javax.swing.InputMap;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JToolBar;
+import javax.swing.KeyStroke;
+import javax.swing.SwingUtilities;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
@@ -59,8 +73,7 @@
 import org.openstreetmap.josm.gui.DefaultNameFormatter;
 import org.openstreetmap.josm.gui.HelpAwareOptionPane;
+import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec;
 import org.openstreetmap.josm.gui.MainMenu;
 import org.openstreetmap.josm.gui.SideButton;
-import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec;
-import org.openstreetmap.josm.gui.dialogs.properties.PresetListPanel;
 import org.openstreetmap.josm.gui.dialogs.properties.PresetListPanel.PresetHandler;
 import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction;
@@ -697,5 +710,5 @@
     }
 
-    static boolean confirmAddingPrimtive(OsmPrimitive primitive) throws AddAbortException {
+    static boolean confirmAddingPrimitive(OsmPrimitive primitive) throws AddAbortException {
         String msg = tr("<html>This relation already has one or more members referring to<br>"
                 + "the object ''{0}''<br>"
@@ -747,5 +760,5 @@
                     continue;
                 } else if (MemberTableModel.hasMembersReferringTo(relation.getMembers(), Collections.singleton(p))
-                        && !confirmAddingPrimtive(p)) {
+                        && !confirmAddingPrimitive(p)) {
                     continue;
                 }
@@ -776,5 +789,5 @@
                 }
                 if (isPotentialDuplicate(primitive))  {
-                    if (confirmAddingPrimtive(primitive)) {
+                    if (confirmAddingPrimitive(primitive)) {
                         ret.add(primitive);
                     }
