Index: applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/OsmTileLoader.java
===================================================================
--- applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/OsmTileLoader.java	(revision 18179)
+++ applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/OsmTileLoader.java	(revision 18211)
@@ -57,4 +57,5 @@
                 } catch (Exception e) {
                     tile.setImage(Tile.ERROR_IMAGE);
+                    tile.error = true;
                     listener.tileLoadingFinished(tile, false);
                     if (input == null)
Index: applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/OsmTileSource.java
===================================================================
--- applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/OsmTileSource.java	(revision 18179)
+++ applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/OsmTileSource.java	(revision 18211)
@@ -6,7 +6,18 @@
 
     public static final String MAP_MAPNIK = "http://tile.openstreetmap.org";
-    public static final String MAP_OSMA = "http://tah.openstreetmap.org/Tiles/tile";
+    public static final String MAP_OSMA = "http://tah.openstreetmap.org/Tiles";
 
-    protected static abstract class AbstractOsmTileSource implements TileSource {
+    public static abstract class AbstractOsmTileSource implements TileSource {
+        protected String NAME;
+        protected String BASE_URL;
+        public AbstractOsmTileSource(String name, String base_url)
+        {
+            NAME = name;
+            BASE_URL = base_url;
+        }
+
+        public String getName() {
+            return NAME;
+        }
 
         public int getMaxZoom() {
@@ -18,6 +29,14 @@
         }
 
+        public String getTilePath(int zoom, int tilex, int tiley) {
+            return "/" + zoom + "/" + tilex + "/" + tiley + ".png";
+        }
+
+        public String getBaseUrl() {
+            return this.BASE_URL;
+        }
+
         public String getTileUrl(int zoom, int tilex, int tiley) {
-            return "/" + zoom + "/" + tilex + "/" + tiley + ".png";
+            return this.getBaseUrl() + getTilePath(zoom, tilex, tiley);
         }
 
@@ -34,14 +53,6 @@
 
     public static class Mapnik extends AbstractOsmTileSource {
-
-        public static String NAME = "Mapnik";
-
-        public String getName() {
-            return NAME;
-        }
-
-        @Override
-        public String getTileUrl(int zoom, int tilex, int tiley) {
-            return MAP_MAPNIK + super.getTileUrl(zoom, tilex, tiley);
+        public Mapnik() {
+            super("Mapnik", MAP_MAPNIK);
         }
 
@@ -54,6 +65,5 @@
     public static class CycleMap extends AbstractOsmTileSource {
 
-        private static final String PATTERN = "http://%s.andy.sandbox.cloudmade.com/tiles/cycle/%d/%d/%d.png";
-        public static String NAME = "OSM Cycle Map";
+        private static final String PATTERN = "http://%s.andy.sandbox.cloudmade.com/tiles/cycle";
 
         private static final String[] SERVER = { "a", "b", "c" };
@@ -61,7 +71,11 @@
         private int SERVER_NUM = 0;
 
+        public CycleMap() {
+            super("OSM Cycle Map", PATTERN);
+        }
+
         @Override
-        public String getTileUrl(int zoom, int tilex, int tiley) {
-            String url = String.format(PATTERN, new Object[] { SERVER[SERVER_NUM], zoom, tilex, tiley });
+        public String getBaseUrl() {
+            String url = String.format(this.BASE_URL, new Object[] { SERVER[SERVER_NUM] });
             SERVER_NUM = (SERVER_NUM + 1) % SERVER.length;
             return url;
@@ -72,8 +86,4 @@
         }
 
-        public String getName() {
-            return NAME;
-        }
-
         public TileUpdate getTileUpdate() {
             return TileUpdate.LastModified;
@@ -82,7 +92,10 @@
     }
 
-    public static class TilesAtHome extends AbstractOsmTileSource {
-
-        public static String NAME = "TilesAtHome";
+    public static abstract class OsmaSource extends AbstractOsmTileSource {
+        String osmaSuffix;
+        public OsmaSource(String name, String osmaSuffix) {
+            super(name, MAP_OSMA);
+            this.osmaSuffix = osmaSuffix;
+        }
 
         public int getMaxZoom() {
@@ -90,11 +103,7 @@
         }
 
-        public String getName() {
-            return NAME;
-        }
-
         @Override
-        public String getTileUrl(int zoom, int tilex, int tiley) {
-            return MAP_OSMA + super.getTileUrl(zoom, tilex, tiley);
+        public String getBaseUrl() {
+            return MAP_OSMA + "/" + osmaSuffix;
         }
 
@@ -103,3 +112,13 @@
         }
     }
+    public static class TilesAtHome extends OsmaSource {
+        public TilesAtHome() {
+            super("TilesAtHome", "tile");
+        }
+    }
+    public static class Maplint extends OsmaSource {
+        public Maplint() {
+            super("Maplint", "maplint");
+        }
+    }
 }
Index: applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/Tile.java
===================================================================
--- applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/Tile.java	(revision 18179)
+++ applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/Tile.java	(revision 18211)
@@ -47,4 +47,5 @@
     protected boolean loaded = false;
     protected boolean loading = false;
+    protected boolean error = false;
     public static final int SIZE = 256;
 
@@ -225,6 +226,11 @@
         if (this.loaded)
             status = "loaded";
+        if (this.error)
+            status = "error";
         return status;
     }
+    public boolean hasError() {
+        return error;
+    }
 
 }
