Index: applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/tilesources/TemplatedTMSTileSource.java
===================================================================
--- applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/tilesources/TemplatedTMSTileSource.java	(revision 36381)
+++ applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/tilesources/TemplatedTMSTileSource.java	(revision 36433)
@@ -30,4 +30,5 @@
  * <li>{!y} - substituted with Yahoo Y tile number</li>
  * <li>{-y} - substituted with reversed Y tile number</li>
+ * <li>{quad} - Microsoft style quadkey</li>
  * <li>{apikey} - substituted with API key retrieved for the imagery id</li>
  * <li>{switch:VAL_A,VAL_B,VAL_C,...} - substituted with one of VAL_A, VAL_B, VAL_C. Usually
@@ -45,13 +46,15 @@
     private static final Pattern PATTERN_Y_YAHOO = Pattern.compile("\\{!y}");
     private static final Pattern PATTERN_NEG_Y   = Pattern.compile("\\{-y}");
+    private static final Pattern PATTERN_QUAD    = Pattern.compile("\\{quad}");
     private static final Pattern PATTERN_SWITCH  = Pattern.compile("\\{switch:([^}]+)}");
     private static final Pattern PATTERN_HEADER  = Pattern.compile("\\{header\\(([^,]+),([^}]+)\\)}");
     private static final Pattern PATTERN_API_KEY = Pattern.compile("\\{apikey}");
-    private static final Pattern PATTERN_PARAM  = Pattern.compile("\\{((?:\\d+-)?z(?:oom)?(:?[+-]\\d+)?|x|y|!y|-y|switch:([^}]+))}");
+    private static final Pattern PATTERN_PARAM  = Pattern.compile("\\{((?:\\d+-)?z(?:oom)?(:?[+-]\\d+)?|x|y|!y|-y|quad|switch:([^}]+))}");
 
     // CHECKSTYLE.ON: SingleSpaceSeparator
 
     private static final Pattern[] ALL_PATTERNS = {
-            PATTERN_HEADER, PATTERN_ZOOM, PATTERN_X, PATTERN_Y, PATTERN_Y_YAHOO, PATTERN_NEG_Y, PATTERN_SWITCH, PATTERN_API_KEY
+            PATTERN_HEADER, PATTERN_ZOOM, PATTERN_X, PATTERN_Y, PATTERN_Y_YAHOO, PATTERN_NEG_Y, PATTERN_SWITCH, PATTERN_API_KEY,
+            PATTERN_QUAD
     };
 
@@ -156,4 +159,7 @@
                 replacement = getRandomPart(randomParts);
                 break;
+            case "quad": // PATTERN_QUAD
+                replacement = xyzToQuadKey(tilex, tiley, zoom);
+                break;
             default:
                 // handle switch/zoom here, as group will contain parameters and switch will not work
@@ -170,4 +176,27 @@
         matcher.appendTail(url);
         return url.toString().replace(" ", "%20");
+    }
+
+    /**
+     * Convert an x y z coordinate to a quadkey
+     * @param x The x coordinate
+     * @param y The y coordinate
+     * @param z The z coordinate
+     * @return The quadkey
+     */
+    private static String xyzToQuadKey(int x, int y, int z) {
+        final char[] string = new char[z];
+        for (int i = z; i > 0; i--) {
+            char digit = '0';
+            final int mask = 1 << (i - 1);
+            if ((x & mask) != 0) {
+                digit++;
+            }
+            if ((y & mask) != 0) {
+                digit += 2;
+            }
+            string[z - i] = digit;
+        }
+        return String.valueOf(string);
     }
 
