Index: /trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java	(revision 8424)
+++ /trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java	(revision 8425)
@@ -96,5 +96,5 @@
     private static ConcurrentMap<String, Boolean> useHead = new ConcurrentHashMap<>();
 
-    private long now; // when the job started
+    protected long now; // when the job started
 
     private ICacheAccess<K, V> cache;
@@ -398,5 +398,5 @@
     protected abstract V createCacheEntry(byte[] content);
 
-    private CacheEntryAttributes parseHeaders(URLConnection urlConn) {
+    protected CacheEntryAttributes parseHeaders(URLConnection urlConn) {
         CacheEntryAttributes ret = new CacheEntryAttributes();
 
Index: /trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java	(revision 8424)
+++ /trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java	(revision 8425)
@@ -7,4 +7,5 @@
 import java.io.IOException;
 import java.net.URL;
+import java.net.URLConnection;
 import java.util.HashSet;
 import java.util.List;
@@ -38,7 +39,10 @@
  */
 public class TMSCachedTileLoaderJob extends JCSCachedTileLoaderJob<String, BufferedImageCacheEntry> implements TileJob, ICachedLoaderListener  {
-    private static final Logger log = FeatureAdapter.getLogger(TMSCachedTileLoaderJob.class.getCanonicalName());
+    private static final Logger LOG = FeatureAdapter.getLogger(TMSCachedTileLoaderJob.class.getCanonicalName());
+    private static final long MAXIMUM_EXPIRES = 30 /*days*/ * 24 /*hours*/ * 60 /*minutes*/ * 60 /*seconds*/ *1000L /*milliseconds*/;
+    private static final long MINIMUM_EXPIRES = 1 /*hour*/ * 60 /*minutes*/ * 60 /*seconds*/ *1000L /*milliseconds*/;
     private Tile tile;
     private volatile URL url;
+
 
     // we need another deduplication of Tile Loader listeners, as for each submit, new TMSCachedTileLoaderJob was created
@@ -105,6 +109,6 @@
                 }
             } catch (IOException e) {
-                log.log(Level.WARNING, "JCS TMS Cache - error creating URL for tile {0}: {1}", new Object[] {tile.getKey(), e.getMessage()});
-                log.log(Level.INFO, "Exception: ", e);
+                LOG.log(Level.WARNING, "JCS TMS Cache - error creating URL for tile {0}: {1}", new Object[] {tile.getKey(), e.getMessage()});
+                LOG.log(Level.INFO, "Exception: ", e);
             }
         }
@@ -119,5 +123,5 @@
                 return content != null  || cacheData.getImage() != null || isNoTileAtZoom();
             } catch (IOException e) {
-                log.log(Level.WARNING, "JCS TMS - error loading from cache for tile {0}: {1}", new Object[] {tile.getKey(), e.getMessage()});
+                LOG.log(Level.WARNING, "JCS TMS - error loading from cache for tile {0}: {1}", new Object[] {tile.getKey(), e.getMessage()});
             }
         }
@@ -127,5 +131,5 @@
     private boolean isNoTileAtZoom() {
         if (attributes == null) {
-            log.warning("Cache attributes are null");
+            LOG.warning("Cache attributes are null");
         }
         return attributes != null && attributes.isNoTileAtZoom();
@@ -146,5 +150,5 @@
     private boolean handleNoTileAtZoom() {
         if (isNoTileAtZoom()) {
-            log.log(Level.FINE, "JCS TMS - Tile valid, but no file, as no tiles at this level {0}", tile);
+            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");
             tile.putValue("tile-info", "no-tile");
@@ -207,5 +211,5 @@
             }
         } catch (IOException e) {
-            log.log(Level.WARNING, "JCS TMS - error loading object for tile {0}: {1}", new Object[] {tile.getKey(), e.getMessage()});
+            LOG.log(Level.WARNING, "JCS TMS - error loading object for tile {0}: {1}", new Object[] {tile.getKey(), e.getMessage()});
             tile.setError(e.getMessage());
             tile.setLoaded(false);
@@ -246,5 +250,5 @@
                 return tile;
             } catch (IOException e) {
-                log.log(Level.WARNING, "JCS TMS - error loading object for tile {0}: {1}", new Object[] {tile.getKey(), e.getMessage()});
+                LOG.log(Level.WARNING, "JCS TMS - error loading object for tile {0}: {1}", new Object[] {tile.getKey(), e.getMessage()});
                 return null;
             }
@@ -288,3 +292,17 @@
         submit(false);
     }
+
+    @Override
+    protected CacheEntryAttributes parseHeaders(URLConnection urlConn) {
+        CacheEntryAttributes ret = super.parseHeaders(urlConn);
+        // keep the expiration time between MINIMUM_EXPIRES and MAXIMUM_EXPIRES, so we will cache the tiles
+        // at least for some short period of time, but not too long
+        if (ret.getExpirationTime() < MINIMUM_EXPIRES) {
+            ret.setExpirationTime(now + MINIMUM_EXPIRES);
+        }
+        if (ret.getExpirationTime() > MAXIMUM_EXPIRES) {
+            ret.setExpirationTime(now + MAXIMUM_EXPIRES);
+        }
+        return ret;
+    }
 }
