Index: trunk/src/org/openstreetmap/josm/data/cache/ICachedLoaderListener.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/cache/ICachedLoaderListener.java	(revision 8175)
+++ trunk/src/org/openstreetmap/josm/data/cache/ICachedLoaderListener.java	(revision 8176)
@@ -3,11 +3,24 @@
 
 public interface ICachedLoaderListener {
+
     /**
-     * Will be called when K object was successfully downloaded
-     * 
+     * Result of download
+     *
+     */
+    enum LoadResult {
+        SUCCESS,
+        FAILURE,
+        REJECTED
+    }
+    /**
+     * Will be called when K object processed. The result might be:
+     * LoadResult.SUCCESS when object was fetched
+     * LoadResult.FAILURE when there was a failure during download
+     * LoadResult.REJECTED when job was rejected because of full queue
+     *
      * @param data
-     * @param success
+     * @param result
      */
-    public void loadingFinished(CacheEntry data, boolean success);
+    public void loadingFinished(CacheEntry data, LoadResult result);
 
 }
Index: trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java	(revision 8175)
+++ trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java	(revision 8176)
@@ -27,4 +27,5 @@
 import org.apache.commons.jcs.engine.behavior.ICacheElement;
 import org.openstreetmap.gui.jmapviewer.FeatureAdapter;
+import org.openstreetmap.josm.data.cache.ICachedLoaderListener.LoadResult;
 import org.openstreetmap.josm.data.preferences.IntegerProperty;
 
@@ -152,5 +153,5 @@
                 // we got something in cache, and it's valid, so lets return it
                 log.log(Level.FINE, "JCS - Returning object from cache: {0}", getCacheKey());
-                finishLoading(true);
+                finishLoading(LoadResult.SUCCESS);
                 return;
             }
@@ -162,5 +163,5 @@
                 // queue was full, try again later
                 log.log(Level.FINE, "JCS - rejected job for: {0}", getCacheKey());
-                finishLoading(false);
+                finishLoading(LoadResult.REJECTED);
             }
         }
@@ -206,14 +207,14 @@
             // try to load object from remote resource
             if (loadObject()) {
-                finishLoading(true);
+                finishLoading(LoadResult.SUCCESS);
             } else {
                 // if loading failed - check if we can return stale entry
                 if (isObjectLoadable()) {
                     // try to get stale entry in cache
-                    finishLoading(true);
+                    finishLoading(LoadResult.SUCCESS);
                     log.log(Level.FINE, "JCS - found stale object in cache: {0}", getUrl());
                 } else {
                     // failed completely
-                    finishLoading(false);
+                    finishLoading(LoadResult.FAILURE);
                 }
             }
@@ -224,5 +225,5 @@
 
 
-    private void finishLoading(boolean success) {
+    private void finishLoading(LoadResult result) {
         Set<ICachedLoaderListener> listeners = null;
         synchronized (inProgress) {
@@ -235,5 +236,5 @@
         try {
             for (ICachedLoaderListener l: listeners) {
-                l.loadingFinished(cacheData, success);
+                l.loadingFinished(cacheData, result);
             }
         } catch (Exception e) {
@@ -241,5 +242,5 @@
             log.log(Level.FINE, "Stacktrace", e);
             for (ICachedLoaderListener l: listeners) {
-                l.loadingFinished(cacheData, false);
+                l.loadingFinished(cacheData, LoadResult.FAILURE);
             }
 
Index: trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java	(revision 8175)
+++ trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java	(revision 8176)
@@ -133,9 +133,15 @@
     }
 
+    private boolean isNoTileAtZoom() {
+        return attributes != null && attributes.isNoTileAtZoom();
+    }
+
     @Override
     protected boolean cacheAsEmpty() {
-        if (attributes != null && attributes.isNoTileAtZoom()) {
-            // do not remove file - keep the information, that there is no tile, for further requests
-            // the code above will check, if this information is still valid
+        return isNoTileAtZoom();
+    }
+
+    private boolean handleNoTileAtZoom() {
+        if (isNoTileAtZoom()) {
             log.log(Level.FINE, "JCS TMS - Tile valid, but no file, as no tiles at this level {0}", tile);
             tile.setError("No tile at this zoom level");
@@ -143,5 +149,5 @@
             return true;
         }
-        return false; // as there is no other cache to cache the Tile, also cache other empty requests
+        return false;
     }
 
@@ -157,9 +163,23 @@
 
     @Override
-    public void loadingFinished(CacheEntry object, boolean success) {
+    public void loadingFinished(CacheEntry object, LoadResult result) {
         try {
-            loadTile(object, success);
+            tile.finishLoading(); // whatever happened set that loading has finished
+            switch(result){
+            case FAILURE:
+                tile.setError("Problem loading tile");
+            case SUCCESS:
+                handleNoTileAtZoom();
+                if (object != null) {
+                    byte[] content = object.getContent();
+                    if (content != null && content.length > 0) {
+                        tile.loadImage(new ByteArrayInputStream(content));
+                    }
+                }
+            case REJECTED:
+                // do not set anything here, leave waiting sign
+            }
             if (listener != null) {
-                listener.tileLoadingFinished(tile, success);
+                listener.tileLoadingFinished(tile, result.equals(LoadResult.SUCCESS));
             }
         } catch (IOException e) {
@@ -181,5 +201,12 @@
         if (isObjectLoadable()) {
             try {
-                loadTile(data);
+                if (data != null && data.getImage() != null) {
+                    tile.setImage(data.getImage());
+                    tile.finishLoading();
+                }
+                if (isNoTileAtZoom()) {
+                    handleNoTileAtZoom();
+                    tile.finishLoading();
+                }
                 return tile;
             } catch (IOException e) {
@@ -189,29 +216,5 @@
 
         } else {
-            return null;
-        }
-    }
-
-    // loads tile when calling back from cache
-    private void loadTile(CacheEntry object, boolean success) throws IOException {
-        tile.finishLoading();
-        if (object != null) {
-            byte[] content = object.getContent();
-            if (content != null && content.length > 0) {
-                tile.loadImage(new ByteArrayInputStream(content));
-            }
-        }
-        if (!success) {
-            tile.setError("Problem loading tile");
-        }
-    }
-
-    // loads tile when geting stright from cache
-    private void loadTile(BufferedImageCacheEntry object) throws IOException {
-        tile.finishLoading();
-        if (cacheAsEmpty() || object != null) { // if cache as empty object, do not try to load image
-            if (object.getImage() != null) {
-                tile.setImage(object.getImage());
-            }
+            return tile;
         }
     }
