Index: trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 2889)
+++ trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 2890)
@@ -108,4 +108,5 @@
     private static final int FLAG_HAS_DIRECTIONS = 1 << 5;
     private static final int FLAG_TAGGED = 1 << 6;
+    private static final int FLAG_DIRECTION_REVERSED = 1 << 7;
 
     /**
@@ -532,4 +533,5 @@
 
     private static volatile Match directionKeys = null;
+    private static volatile Match reversedDirectionKeys = null;
 
     /**
@@ -538,31 +540,41 @@
      * Initialized by checkDirectionTagged()
      */
-    public static void initDirectionKeys() {
-        if(directionKeys == null) {
-
-            // Legacy support - convert list of keys to search pattern
-            if (Main.pref.isCollection("tags.direction", false)) {
-                System.out.println("Collection of keys in tags.direction is no longer supported, value will converted to search pattern");
-                Collection<String> keys = Main.pref.getCollection("tags.direction", null);
-                StringBuilder builder = new StringBuilder();
-                for (String key:keys) {
-                    builder.append(key);
-                    builder.append("=* | ");
-                }
-                builder.delete(builder.length() - 3, builder.length());
-                Main.pref.put("tags.direction", builder.toString());
-            }
-
-            String defaultValue = "oneway? | incline=* | incline_steep=* | aerialway=* | waterway=stream | waterway=river | waterway=canal | waterway=drain | \"piste:type\"=downhill | \"piste:type\"=sled | man_made=\"piste:halfpipe\" ";
+    static {
+        // Legacy support - convert list of keys to search pattern
+        if (Main.pref.isCollection("tags.direction", false)) {
+            System.out.println("Collection of keys in tags.direction is no longer supported, value will converted to search pattern");
+            Collection<String> keys = Main.pref.getCollection("tags.direction", null);
+            StringBuilder builder = new StringBuilder();
+            for (String key:keys) {
+                builder.append(key);
+                builder.append("=* | ");
+            }
+            builder.delete(builder.length() - 3, builder.length());
+            Main.pref.put("tags.direction", builder.toString());
+        }
+
+        String reversedDirectionDefault = "oneway=\"-1\" | incline=down | incline=\"-*\"";
+        String directionDefault = "oneway? | incline=* | aerialway=* | waterway=stream | waterway=river | waterway=canal | waterway=drain | waterway=rapids | \"piste:type\"=downhill | \"piste:type\"=sled | man_made=\"piste:halfpipe\" ";
+
+        try {
+            reversedDirectionKeys = SearchCompiler.compile(Main.pref.get("tags.reversed_direction", reversedDirectionDefault), false, false);
+        } catch (ParseError e) {
+            System.err.println("Unable to compile pattern for tags.reversed_direction, trying default pattern: " + e.getMessage());
+
             try {
-                directionKeys = SearchCompiler.compile(Main.pref.get("tags.direction", defaultValue), false, false);
-            } catch (ParseError e) {
-                System.err.println("Unable to compile pattern for tags.direction, trying default pattern: " + e.getMessage());
-
-                try {
-                    directionKeys = SearchCompiler.compile(defaultValue, false, false);
-                } catch (ParseError e2) {
-                    throw new AssertionError("Unable to compile default pattern for direction keys: " + e2.getMessage());
-                }
+                reversedDirectionKeys = SearchCompiler.compile(reversedDirectionDefault, false, false);
+            } catch (ParseError e2) {
+                throw new AssertionError("Unable to compile default pattern for direction keys: " + e2.getMessage());
+            }
+        }
+        try {
+            directionKeys = SearchCompiler.compile(Main.pref.get("tags.direction", directionDefault), false, false);
+        } catch (ParseError e) {
+            System.err.println("Unable to compile pattern for tags.direction, trying default pattern: " + e.getMessage());
+
+            try {
+                directionKeys = SearchCompiler.compile(directionDefault, false, false);
+            } catch (ParseError e2) {
+                throw new AssertionError("Unable to compile default pattern for direction keys: " + e2.getMessage());
             }
         }
@@ -576,4 +588,5 @@
      * direction dependent.
      */
+    @Deprecated
     public static Collection<String> getDirectionKeys() {
         return Main.pref.getCollection("tags.direction",
@@ -863,5 +876,5 @@
     private void keysChangedImpl(Map<String, String> originalKeys) {
         clearCached();
-        updateHasDirectionKeys();
+        updateDirectionFlags();
         updateTagged();
         if (dataSet != null) {
@@ -1126,7 +1139,21 @@
     }
 
-    private void updateHasDirectionKeys() {
-        initDirectionKeys();
+    private void updateDirectionFlags() {
+        boolean hasDirections = false;
+        boolean directionReversed = false;
+        if (reversedDirectionKeys.match(this)) {
+            hasDirections = true;
+            directionReversed = true;
+        }
         if (directionKeys.match(this)) {
+            hasDirections = true;
+        }
+
+        if (directionReversed) {
+            flags |= FLAG_DIRECTION_REVERSED;
+        } else {
+            flags &= ~FLAG_DIRECTION_REVERSED;
+        }
+        if (hasDirections) {
             flags |= FLAG_HAS_DIRECTIONS;
         } else {
@@ -1142,4 +1169,7 @@
     }
 
+    public boolean reversedDirection() {
+        return (flags & FLAG_DIRECTION_REVERSED) != 0;
+    }
     /**
      * Replies the name of this primitive. The default implementation replies the value
@@ -1222,5 +1252,4 @@
 
     protected String getFlagsAsString() {
-
         StringBuilder builder = new StringBuilder();
 
@@ -1240,9 +1269,17 @@
             builder.append("f");
         }
-
-        if (isDeleted()) {
+        if (isDisabled()) {
             builder.append("d");
         }
-
+        if (isTagged()) {
+            builder.append("T");
+        }
+        if (hasDirectionKeys()) {
+            if (reversedDirection()) {
+                builder.append("<");
+            } else {
+                builder.append(">");
+            }
+        }
         return builder.toString();
     }
Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java	(revision 2889)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java	(revision 2890)
@@ -27,6 +27,4 @@
 
 public class MapPainter {
-    private static final double PHI = Math.toRadians(20);
-
     private final Graphics2D g;
     private final NavigatableComponent nc;
@@ -81,5 +79,5 @@
 
     public void drawWay(Way way, Color color, int width, float dashed[], Color dashedColor, boolean showDirection,
-            boolean showHeadArrowOnly) {
+            boolean reversedDirection, boolean showHeadArrowOnly) {
 
         GeneralPath path = new GeneralPath();
@@ -91,5 +89,5 @@
             Point p = nc.getPoint(n);
             if(lastPoint != null) {
-                drawSegment(path, lastPoint, p, (showHeadArrowOnly ? !it.hasNext() : showDirection));
+                drawSegment(path, lastPoint, p, showHeadArrowOnly ? !it.hasNext() : showDirection, reversedDirection);
             }
             lastPoint = p;
@@ -128,14 +126,32 @@
     }
 
-    private void drawSegment(GeneralPath path, Point p1, Point p2, boolean showDirection) {
+    private static final double PHI = Math.toRadians(20);
+    private static final double cosPHI = Math.cos(PHI);
+    private static final double sinPHI = Math.sin(PHI);
+
+    private void drawSegment(GeneralPath path, Point p1, Point p2, boolean showDirection, boolean reversedDirection) {
         if (isSegmentVisible(p1, p2)) {
+
+            /* draw segment line */
             path.moveTo(p1.x, p1.y);
             path.lineTo(p2.x, p2.y);
 
+            /* draw arrow */
             if (showDirection) {
-                double t = Math.atan2(p2.y-p1.y, p2.x-p1.x) + Math.PI;
-                path.lineTo((int)(p2.x + 10*Math.cos(t-PHI)), (int)(p2.y + 10*Math.sin(t-PHI)));
-                path.moveTo((int)(p2.x + 10*Math.cos(t+PHI)), (int)(p2.y + 10*Math.sin(t+PHI)));
-                path.lineTo(p2.x, p2.y);
+                Point q1 = p1;
+                Point q2 = p2;
+                if (reversedDirection) {
+                    q1 = p2;
+                    q2 = p1;
+                    path.moveTo(q2.x, q2.y);
+                }
+                final double l =  10. / q1.distance(q2);
+
+                final double sx = l * (q1.x - q2.x);
+                final double sy = l * (q1.y - q2.y);
+
+                path.lineTo (q2.x + (int) Math.round(cosPHI * sx - sinPHI * sy), q2.y + (int) Math.round(sinPHI * sx + cosPHI * sy));
+                path.moveTo (q2.x + (int) Math.round(cosPHI * sx + sinPHI * sy), q2.y + (int) Math.round(- sinPHI * sx + cosPHI * sy));
+                path.lineTo(q2.x, q2.y);
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/LineElemStyle.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/LineElemStyle.java	(revision 2889)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/LineElemStyle.java	(revision 2890)
@@ -146,4 +146,5 @@
         boolean showDirection = selected || ((!paintSettings.isUseRealWidth()) && (paintSettings.isShowDirectionArrow()
                 && (!paintSettings.isShowRelevantDirectionsOnly() || w.hasDirectionKeys())));
+        boolean reversedDirection = w.reversedDirection();
         /* head only takes over control if the option is true,
         the direction should be shown at all and not only because it's selected */
@@ -189,5 +190,5 @@
                 if(!s.over) {
                     painter.drawWay(w, s.color != null && selected ? myColor: s.color, s.getWidth(myWidth),
-                            s.getDashed(), s.dashedColor, false, false);
+                            s.getDashed(), s.dashedColor, false, false, false);
                 }
             }
@@ -195,5 +196,5 @@
 
         /* draw the way */
-        painter.drawWay(w, myColor, myWidth, dashed, dashedColor, showDirection, showOnlyHeadArrowOnly);
+        painter.drawWay(w, myColor, myWidth, dashed, dashedColor, showDirection, selected ? false : reversedDirection, showOnlyHeadArrowOnly);
 
         /* draw overlays above the way */
@@ -202,5 +203,5 @@
                 if(s.over) {
                     painter.drawWay(w, s.color != null && selected ? myColor : s.color, s.getWidth(myWidth),
-                            s.getDashed(), s.dashedColor, false, false);
+                            s.getDashed(), s.dashedColor, false, false, false);
                 }
             }
