Index: src/org/openstreetmap/josm/actions/CombineWayAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/CombineWayAction.java	(revision 2566)
+++ src/org/openstreetmap/josm/actions/CombineWayAction.java	(working copy)
@@ -27,6 +27,8 @@
 import org.openstreetmap.josm.command.Command;
 import org.openstreetmap.josm.command.DeleteCommand;
 import org.openstreetmap.josm.command.SequenceCommand;
+import org.openstreetmap.josm.corrector.ReverseWayTagCorrector;
+import org.openstreetmap.josm.corrector.UserCancelException;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Relation;
@@ -36,6 +38,7 @@
 import org.openstreetmap.josm.gui.conflict.tags.CombinePrimitiveResolverDialog;
 import org.openstreetmap.josm.tools.Pair;
 import org.openstreetmap.josm.tools.Shortcut;
+
 /**
  * Combines multiple ways into one.
  *
@@ -108,27 +111,75 @@
         ways.remove(null); // just in case -  remove all null ways from the collection
         ways = new HashSet<Way>(ways); // remove duplicates
 
-        // build the collection of tags used by the ways to combine
-        //
-        TagCollection wayTags = TagCollection.unionOfAllPrimitives(ways);
-
         // try to build a new way which includes all the combined
         // ways
         //
-        NodeGraph graph = NodeGraph.createDirectedGraphFromWays(ways);
+        NodeGraph graph = NodeGraph.createUndirectedGraphFromNodeWays(ways);
         List<Node> path = graph.buildSpanningPath();
         if (path == null) {
-            graph = NodeGraph.createUndirectedGraphFromNodeWays(ways);
-            path = graph.buildSpanningPath();
-            if (path != null) {
-                if (!confirmChangeDirectionOfWays())
-                    return;
+            warnCombiningImpossible();
+            return;
+        }
+        // check whether any ways have been reversed in the process
+        // and build the collection of tags used by the ways to combine
+        //
+        TagCollection wayTags = TagCollection.unionOfAllPrimitives(ways);
+
+        List<Way> reversedWays = new LinkedList<Way>();
+        List<Way> unreversedWays = new LinkedList<Way>();
+        for (Way w: ways) {
+            if ((path.indexOf(w.getNode(0)) + 1) == path.lastIndexOf(w.getNode(1))) {
+                unreversedWays.add(w);
             } else {
-                warnCombiningImpossible();
-                return;
+                reversedWays.add(w);
             }
         }
+        // reverse path if all ways have been reversed
+        if (unreversedWays.isEmpty()) {
+            Collections.reverse(path);
+            unreversedWays = reversedWays;
+            reversedWays = null;
+        }
+        if ((reversedWays != null) && !reversedWays.isEmpty()) {
+            if (!confirmChangeDirectionOfWays()) return;
+            // filter out ways that have no direction-dependent tags
+            unreversedWays = ReverseWayTagCorrector.irreversibleWays(unreversedWays);
+            reversedWays = ReverseWayTagCorrector.irreversibleWays(reversedWays);
+            // reverse path if there are more reversed than unreversed ways with direction-dependent tags
+            if (reversedWays.size() > unreversedWays.size()) {
+                Collections.reverse(path);
+                List<Way> tempWays = unreversedWays;
+                unreversedWays = reversedWays;
+                reversedWays = tempWays;
+            }
+            // if there are still reversed ways with direction-dependent tags, reverse their tags
+            if (!reversedWays.isEmpty() && Main.pref.getBoolean("tag-correction.reverse-way", true)) {
+                List<Way> unreversedTagWays = new ArrayList<Way>(ways);
+                unreversedTagWays.removeAll(reversedWays);
+                ReverseWayTagCorrector reverseWayTagCorrector = new ReverseWayTagCorrector();
+                List<Way> reversedTagWays = new ArrayList<Way>();
+                Collection<Command> changePropertyCommands =  null;
+                for (Way w : reversedWays) {
+                    Way wnew = new Way(w);
+                    reversedTagWays.add(wnew);
+                    try {
+                        changePropertyCommands = reverseWayTagCorrector.execute(w, wnew);
+                    }
+                    catch(UserCancelException ex) {
+                        return;
+                    }
+                }
+                if ((changePropertyCommands != null) && !changePropertyCommands.isEmpty()) {
+                    for (Command c : changePropertyCommands) {
+                        c.executeCommand();
+                    }
+                }
+                wayTags = TagCollection.unionOfAllPrimitives(reversedTagWays);
+                wayTags.add(TagCollection.unionOfAllPrimitives(unreversedTagWays));
+            }
+        }
 
+
         // create the new way and apply the new node list
         //
         Way targetWay = getTargetWay(ways);
Index: src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java
===================================================================
--- src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java	(revision 2566)
+++ src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java	(working copy)
@@ -68,10 +68,37 @@
         new PrefixSuffixSwitcher("forwards", "backwards")
     };
 
+    public static boolean isReversible(Way way) {
+        ArrayList<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>();
+        primitives.add(way);
+        primitives.addAll(way.getNodes());
+
+        for  (OsmPrimitive primitive : primitives) {
+            for (String key : primitive.keySet()) {
+                if (key.equals("oneway")) return false;
+                for (PrefixSuffixSwitcher prefixSuffixSwitcher : prefixSuffixSwitchers) {
+                    if (!key.equals(prefixSuffixSwitcher.apply(key))) return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    public static List<Way> irreversibleWays(List<Way> ways) {
+        List<Way> newWays = new ArrayList<Way>(ways);
+        for (Way way : ways) {
+            if (isReversible(way)) {
+                newWays.remove(way);
+            }
+        }
+        return newWays;
+    }
+
     @Override
     public Collection<Command> execute(Way oldway, Way way) throws UserCancelException {
         Map<OsmPrimitive, List<TagCorrection>> tagCorrectionsMap =
-                new HashMap<OsmPrimitive, List<TagCorrection>>();
+            new HashMap<OsmPrimitive, List<TagCorrection>>();
 
         ArrayList<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>();
         primitives.add(way);
@@ -86,12 +113,12 @@
                 String newValue = value;
 
                 if (key.equals("oneway")) {
-                    if (value.equals("-1")) {
+                    if (OsmUtils.isReversed(value)) {
                         newValue = OsmUtils.trueval;
                     } else {
                         Boolean boolValue = OsmUtils.getOsmBoolean(value);
                         if (boolValue != null && boolValue.booleanValue()) {
-                            newValue = "-1";
+                            newValue = OsmUtils.reverseval;
                         }
                     }
                 } else {
@@ -111,7 +138,7 @@
         }
 
         Map<OsmPrimitive, List<RoleCorrection>> roleCorrectionMap =
-                new HashMap<OsmPrimitive, List<RoleCorrection>>();
+            new HashMap<OsmPrimitive, List<RoleCorrection>>();
         roleCorrectionMap.put(way, new ArrayList<RoleCorrection>());
 
         for (Relation relation : Main.main.getCurrentDataSet().getRelations()) {
Index: src/org/openstreetmap/josm/data/osm/OsmUtils.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/OsmUtils.java	(revision 2566)
+++ src/org/openstreetmap/josm/data/osm/OsmUtils.java	(working copy)
@@ -11,9 +11,12 @@
             .asList(new String[] { "true", "yes", "1", "on" }));
     static ArrayList<String> FALSE_VALUES = new ArrayList<String>(Arrays
             .asList(new String[] { "false", "no", "0", "off" }));
+    static ArrayList<String> REVERSE_VALUES = new ArrayList<String>(Arrays
+            .asList(new String[] { "reverse", "-1" }));
 
     public static final String trueval = "yes";
     public static final String falseval = "no";
+    public static final String reverseval = "-1";
 
     public static Boolean getOsmBoolean(String value) {
         if(value == null) return null;
@@ -22,8 +25,13 @@
         if (FALSE_VALUES.contains(lowerValue)) return Boolean.FALSE;
         return null;
     }
+
     public static String getNamedOsmBoolean(String value) {
         Boolean res = getOsmBoolean(value);
         return res == null ? value : (res ? trueval : falseval);
     }
+
+    public static boolean isReversed(String value) {
+        return REVERSE_VALUES.contains(value);
+    }
 }
