Index: applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/OsmFileCacheTileLoader.java
===================================================================
--- applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/OsmFileCacheTileLoader.java	(revision 24847)
+++ applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/OsmFileCacheTileLoader.java	(revision 24967)
@@ -203,5 +203,11 @@
                 saveTagsToFile();
 
-                byte[] buffer = loadTileInBuffer(urlConn);
+                byte[] buffer = null;
+                if ("no-tile".equals(tile.getValue("tile-info")))
+                {
+                    tile.setError("No tile at this zoom level");
+                } else {
+                    buffer = loadTileInBuffer(urlConn);
+                }
                 if (buffer != null) {
                     tile.loadImage(new ByteArrayInputStream(buffer));
@@ -209,10 +215,7 @@
                     listener.tileLoadingFinished(tile, true);
                     saveTileToFile(buffer);
-                } else {
-                    tile.setLoaded(true);
                 }
             } catch (Exception e) {
-                tile.setImage(Tile.ERROR_IMAGE);
-                tile.error = true;
+                tile.setError(e.getMessage());
                 listener.tileLoadingFinished(tile, false);
                 if (input == null) {
@@ -229,11 +232,19 @@
             try {
                 tileFile = getTileFile();
-                fin = new FileInputStream(tileFile);
-                if (fin.available() == 0)
-                    throw new IOException("File empty");
-                tile.loadImage(fin);
-                fin.close();
-
                 loadTagsFromFile();
+                if ("no-tile".equals(tile.getValue("tile-info")))
+                {
+                    tile.setError("No tile at this zoom level");
+                    if (tileFile.exists()) {
+                        tileFile.delete();
+                    }
+                    tileFile = getTagsFile();
+                } else {
+                    fin = new FileInputStream(tileFile);
+                    if (fin.available() == 0)
+                        throw new IOException("File empty");
+                    tile.loadImage(fin);
+                    fin.close();
+                }
 
                 fileAge = tileFile.lastModified();
@@ -333,4 +344,9 @@
         }
 
+        protected File getTagsFile() {
+            return new File(tileCacheDir + "/" + tile.getZoom() + "_" + tile.getXtile() + "_" + tile.getYtile()
+                    + TAGS_FILE_EXT);
+        }
+
         protected void saveTileToFile(byte[] rawData) {
             try {
@@ -346,6 +362,5 @@
 
         protected void saveTagsToFile() {
-            File tagsFile = new File(tileCacheDir, tile.getZoom() + "_"
-                    + tile.getXtile() + "_" + tile.getYtile() + TAGS_FILE_EXT);
+            File tagsFile = getTagsFile();
             if (tile.getMetadata() == null) {
                 tagsFile.delete();
@@ -353,5 +368,6 @@
             }
             try {
-                final PrintWriter f = new PrintWriter(new OutputStreamWriter(new FileOutputStream(tagsFile)));
+                final PrintWriter f = new PrintWriter(new OutputStreamWriter(new FileOutputStream(tagsFile),
+                        TAGS_CHARSET));
                 for (Entry<String, String> entry : tile.getMetadata().entrySet()) {
                     f.println(entry.getKey() + "=" + entry.getValue());
@@ -385,8 +401,8 @@
         protected void loadTagsFromFile() {
             loadOldETagfromFile();
-            File tagsFile = new File(tileCacheDir, tile.getZoom() + "_"
-                    + tile.getXtile() + "_" + tile.getYtile() + TAGS_FILE_EXT);
-            try {
-                final BufferedReader f = new BufferedReader(new InputStreamReader(new FileInputStream(tagsFile)));
+            File tagsFile = getTagsFile();
+            try {
+                final BufferedReader f = new BufferedReader(new InputStreamReader(new FileInputStream(tagsFile),
+                        TAGS_CHARSET));
                 for (String line = f.readLine(); line != null; line = f.readLine()) {
                     final int i = line.indexOf('=');
Index: applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/OsmTileLoader.java
===================================================================
--- applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/OsmTileLoader.java	(revision 24847)
+++ applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/OsmTileLoader.java	(revision 24967)
@@ -52,13 +52,16 @@
                     URLConnection conn = loadTileFromOsm(tile);
                     loadTileMetadata(tile, conn);
-                    input = conn.getInputStream();
-                    tile.loadImage(input);
+                    if ("no-tile".equals(tile.getValue("tile-info"))) {
+                        tile.setError("No tile at this zoom level");
+                    } else {
+                        input = conn.getInputStream();
+                        tile.loadImage(input);
+                        input.close();
+                        input = null;
+                    }
                     tile.setLoaded(true);
                     listener.tileLoadingFinished(tile, true);
-                    input.close();
-                    input = null;
                 } catch (Exception e) {
-                    tile.setImage(Tile.ERROR_IMAGE);
-                    tile.error = true;
+                    tile.setError(e.getMessage());
                     listener.tileLoadingFinished(tile, false);
                     if (input == null) {
@@ -86,7 +89,11 @@
 
     protected void loadTileMetadata(Tile tile, URLConnection urlConn) {
-        String bing_capturedate = urlConn.getHeaderField("X-VE-TILEMETA-CaptureDatesRange");
-        if (bing_capturedate != null) {
-            tile.putValue("capture-date", bing_capturedate);
+        String str = urlConn.getHeaderField("X-VE-TILEMETA-CaptureDatesRange");
+        if (str != null) {
+            tile.putValue("capture-date", str);
+        }
+        str = urlConn.getHeaderField("X-VE-Tile-Info");
+        if (str != null) {
+            tile.putValue("tile-info", str);
         }
     }
Index: applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/Tile.java
===================================================================
--- applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/Tile.java	(revision 24847)
+++ applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/Tile.java	(revision 24967)
@@ -50,4 +50,5 @@
     protected boolean loading = false;
     protected boolean error = false;
+    protected String error_message;
 
     /** TileLoader-specific tile metadata */
@@ -271,4 +272,14 @@
     }
 
+    public String getErrorMessage() {
+        return error_message;
+    }
+
+    public void setError(String message) {
+        error = true;
+        setImage(ERROR_IMAGE);
+        error_message = message;
+    }
+
     public void putValue(String key, String value) {
         if (value == null || "".equals(value)) {
