Index: trunk/src/org/openstreetmap/josm/data/imagery/ImageryInfo.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/imagery/ImageryInfo.java	(revision 4431)
+++ trunk/src/org/openstreetmap/josm/data/imagery/ImageryInfo.java	(revision 4432)
@@ -70,5 +70,4 @@
     private ImageryType imageryType = ImageryType.WMS;
     private double pixelPerDegree = 0.0;
-    private int maxZoom = 0;
     private int defaultMaxZoom = 0;
     private int defaultMinZoom = 0;
@@ -120,6 +119,4 @@
         if(imageryType == ImageryType.WMS || imageryType == ImageryType.HTML) {
             res.add(pixelPerDegree != 0.0 ? String.valueOf(pixelPerDegree) : null);
-        } else {
-            res.add(maxZoom != 0 ? String.valueOf(maxZoom) : null);
         }
         res.add(bounds != null ? bounds.encodeAsString(",") : null);
@@ -163,6 +160,4 @@
             if (imageryType == ImageryType.WMS || imageryType == ImageryType.HTML) {
                 this.pixelPerDegree=Double.valueOf(array.get(3));
-            } else {
-                this.maxZoom=Integer.valueOf(array.get(3));
             }
         }
@@ -206,5 +201,4 @@
         this.imageryType=i.imageryType;
         this.defaultMinZoom=i.defaultMinZoom;
-        this.maxZoom=i.maxZoom;
         this.defaultMaxZoom=i.defaultMaxZoom;
         this.pixelPerDegree=i.pixelPerDegree;
@@ -251,8 +245,4 @@
     }
     
-    public void setMaxZoom(int maxZoom) {
-        this.maxZoom = maxZoom;
-    }
-
     public void setBounds(ImageryBounds b) {
         this.bounds = b;
@@ -282,4 +272,8 @@
         CheckParameterUtil.ensureParameterNotNull(url);
         
+        // Default imagery type is WMS
+        this.url = url;
+        this.imageryType = ImageryType.WMS;
+
         defaultMaxZoom = 0;
         defaultMinZoom = 0;
@@ -291,16 +285,54 @@
                 if(m.group(2) != null) {
                     defaultMaxZoom = Integer.valueOf(m.group(2));
-                    maxZoom = defaultMaxZoom;
                 }
                 if(m.group(1) != null) {
                     defaultMinZoom = Integer.valueOf(m.group(1));
                 }
-                return;
-            }
-        }
-
-        // Default imagery type is WMS
-        this.url = url;
-        this.imageryType = ImageryType.WMS;
+                break;
+            }
+        }
+
+        if(url.contains("{") && url.contains("}")) {
+            if(serverProjections == null || serverProjections.isEmpty()) {
+                try {
+                    serverProjections = new ArrayList<String>();
+                    Matcher m = Pattern.compile(".*\\{PROJ\\(([^)}]+)\\)\\}.*").matcher(url.toUpperCase());
+                    if(m.matches()) {
+                        for(String p : m.group(1).split(","))
+                            serverProjections.add(p);
+                    }
+                } catch(Exception e) {
+                }
+            }
+        // FIXME: Remove else case in March 2012 - convert old style WMS/TMS
+        } else {
+            url = this.url;
+            if(imageryType == ImageryType.WMS) {
+                if(!url.endsWith("&") && !url.endsWith("?")) {
+                    url = url + (url.contains("?") ? "&" : "?");
+                }
+                try {
+                    Matcher m = Pattern.compile(".*SRS=([a-z0-9:]+).*", Pattern.CASE_INSENSITIVE).matcher(url.toUpperCase());
+                    if(m.matches()) {
+                        String newProj = m.group(1);
+                        if(serverProjections == null || serverProjections.isEmpty())
+                            serverProjections = Collections.singletonList(newProj);
+                        url = url.replaceAll("([sS][rR][sS]=)[a-zA-Z0-9:]+","SRS={proj("+newProj+")}");
+                    } else
+                        url += "SRS={proj}&";
+                } catch(Exception e) {
+                }
+                url += "WIDTH={width}&height={HEIGHT}&BBOX={bbox}";
+            }
+            else if(imageryType == ImageryType.TMS) {
+                if(!url.endsWith("/"))
+                    url += "/";
+                url += "{zoom}/{x}/{y}.png";
+            }
+            if(!url.equals(this.url)) {
+                Main.warn("Changed Imagery URL '"+this.url+"' to '"+url+"'");
+                this.url = url;
+            }
+        }
     }
 
@@ -338,5 +370,5 @@
 
     public int getMaxZoom() {
-        return this.maxZoom;
+        return this.defaultMaxZoom;
     }
 
@@ -368,5 +400,6 @@
      */
     public List<String> getServerProjections() {
-        if (serverProjections == null) return null;
+        if (serverProjections == null)
+            return Collections.emptyList();
         return Collections.unmodifiableList(serverProjections);
     }
@@ -395,6 +428,4 @@
         if(pixelPerDegree != 0.0) {
             res += " ("+pixelPerDegree+")";
-        } else if(maxZoom != 0 && maxZoom != defaultMaxZoom) {
-            res += " (z"+maxZoom+")";
         }
         return res;
@@ -447,8 +478,4 @@
     public void setImageryType(ImageryType imageryType) {
         this.imageryType = imageryType;
-    }
-
-    public static boolean isUrlWithPatterns(String url) {
-        return url != null && url.contains("{") && url.contains("}");
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/LayerListDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/LayerListDialog.java	(revision 4431)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/LayerListDialog.java	(revision 4432)
@@ -905,5 +905,6 @@
                     }
                 }
-                /* Setting foreground properly handles null as default! */
+                if(c == null)
+                    c = Main.pref.getUIColor(isSelected ? "Table.selectionForeground" : "Table.foreground");
                 label.setForeground(c);
             }
Index: trunk/src/org/openstreetmap/josm/gui/layer/TMSLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/TMSLayer.java	(revision 4431)
+++ trunk/src/org/openstreetmap/josm/gui/layer/TMSLayer.java	(revision 4432)
@@ -236,13 +236,7 @@
     public static TileSource getTileSource(ImageryInfo info) {
         if (info.getImageryType() == ImageryType.TMS) {
-            if(ImageryInfo.isUrlWithPatterns(info.getUrl())) {
-                TMSTileSource t = new TemplatedTMSTileSource(info.getName(), info.getUrl(), info.getMinZoom(), info.getMaxZoom());
-                info.setAttribution(t);
-                return t;
-            } else {
-                TMSTileSource t = new TMSTileSource(info.getName(),info.getUrl(), info.getMinZoom(), info.getMaxZoom());
-                info.setAttribution(t);
-                return t;
-            }
+            TMSTileSource t = new TemplatedTMSTileSource(info.getName(), info.getUrl(), info.getMinZoom(), info.getMaxZoom());
+            info.setAttribution(t);
+            return t;
         } else if (info.getImageryType() == ImageryType.BING)
             return new BingAerialTileSource();
Index: trunk/src/org/openstreetmap/josm/gui/layer/WMSLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/WMSLayer.java	(revision 4431)
+++ trunk/src/org/openstreetmap/josm/gui/layer/WMSLayer.java	(revision 4432)
@@ -109,5 +109,4 @@
     private int workingThreadCount;
     private boolean canceled;
-    private List<String> serverProjections = null;
 
     /** set to true if this layer uses an invalid base url */
@@ -122,5 +121,4 @@
     public WMSLayer(ImageryInfo info) {
         super(info);
-        serverProjections = info.getServerProjections();
         mv = Main.map.mapView;
         setBackgroundLayer(true); /* set global background variable */
@@ -144,22 +142,6 @@
         resolution = mv.getDist100PixelText();
 
-        if(info.getUrl() != null) {
-            if (serverProjections == null) {
-                serverProjections = WMSGrabber.getServerProjections(info.getUrl(), true);
-            }
+        if(info.getUrl() != null)
             startGrabberThreads();
-            if(info.getImageryType() == ImageryType.WMS && !ImageryInfo.isUrlWithPatterns(info.getUrl())) {
-                if (!(info.getUrl().endsWith("&") || info.getUrl().endsWith("?"))) {
-                    if (!confirmMalformedUrl(info.getUrl())) {
-                        System.out.println(tr("Warning: WMS layer deactivated because of malformed base url ''{0}''", info.getUrl()));
-                        usesInvalidUrl = true;
-                        setName(getName() + tr("(deactivated)"));
-                        return;
-                    } else {
-                        isInvalidUrlConfirmed = true;
-                    }
-                }
-            }
-        }
 
         Main.pref.addPreferenceChangeListener(this);
@@ -247,33 +229,4 @@
         } else {
             downloadAndPaintVisible(g, mv, false);
-        }
-    }
-
-    protected boolean confirmMalformedUrl(String url) {
-        if (isInvalidUrlConfirmed)
-            return true;
-        String msg  = tr("<html>The base URL<br>"
-                + "''{0}''<br>"
-                + "for this WMS layer does neither end with a ''&'' nor with a ''?''.<br>"
-                + "This is likely to lead to invalid WMS request. You should check your<br>"
-                + "preference settings.<br>"
-                + "Do you want to fetch WMS tiles anyway?</html>",
-                url);
-        String [] options = new String[] {
-                tr("Yes, fetch images"),
-                tr("No, abort")
-        };
-        int ret = JOptionPane.showOptionDialog(
-                Main.parent,
-                msg,
-                tr("Invalid URL?"),
-                JOptionPane.YES_NO_OPTION,
-                JOptionPane.WARNING_MESSAGE,
-                null,
-                options, options[1]
-        );
-        switch(ret) {
-        case JOptionPane.YES_OPTION: return true;
-        default: return false;
         }
     }
@@ -918,18 +871,8 @@
     }
 
-    /**
-     * Get the list of projections supported by the WMS server corresponding to this layer.
-     * @return The list of projections, if known. An empty list otherwise.
-     */
-    public List<String> getServerProjections() {
-        if (serverProjections == null)
-            return Collections.emptyList();
-        else
-            return Collections.unmodifiableList(serverProjections);
-    }
-    
     @Override
     public boolean isProjectionSupported(Projection proj) {
-        return serverProjections == null || serverProjections.contains(proj.toCode().toUpperCase())
+        List<String> serverProjections = info.getServerProjections();
+        return serverProjections.contains(proj.toCode().toUpperCase())
         || (proj instanceof Mercator && serverProjections.contains("EPSG:4326"));
     }
@@ -938,5 +881,5 @@
     public String nameSupportedProjections() {
         String res = "";
-        for(String p : serverProjections) {
+        for(String p : info.getServerProjections()) {
             if(!res.isEmpty())
                 res += ", ";
Index: trunk/src/org/openstreetmap/josm/gui/preferences/ImageryPreference.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/ImageryPreference.java	(revision 4431)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/ImageryPreference.java	(revision 4432)
@@ -449,5 +449,4 @@
 
             mod = listActive.getColumnModel();
-            mod.getColumn(2).setPreferredWidth(50);
             mod.getColumn(1).setPreferredWidth(800);
             mod.getColumn(0).setPreferredWidth(200);
@@ -722,5 +721,5 @@
         class ImageryLayerTableModel extends DefaultTableModel {
             public ImageryLayerTableModel() {
-                setColumnIdentifiers(new String[] { tr("Menu Name"), tr("Imagery URL"), trc("layer", "Zoom") });
+                setColumnIdentifiers(new String[] { tr("Menu Name"), tr("Imagery URL")});
             }
 
@@ -754,8 +753,4 @@
                 case 1:
                     return info.getExtendedUrl();
-                case 2:
-                    return (info.getImageryType() == ImageryType.WMS || info.getImageryType() == ImageryType.HTML) ?
-                            (info.getPixelPerDegree() == 0.0 ? "" : info.getPixelPerDegree()) :
-                                (info.getMaxZoom() == 0 ? "" : info.getMaxZoom());
                 default:
                     throw new ArrayIndexOutOfBoundsException();
@@ -772,16 +767,4 @@
                 case 1:
                     info.setExtendedUrl((String)o);
-                    break;
-                case 2:
-                    info.setPixelPerDegree(0);
-                    info.setMaxZoom(0);
-                    try {
-                        if(info.getImageryType() == ImageryType.WMS || info.getImageryType() == ImageryType.HTML) {
-                            info.setPixelPerDegree(Double.parseDouble((String) o));
-                        } else {
-                            info.setMaxZoom(Integer.parseInt((String) o));
-                        }
-                    } catch (NumberFormatException e) {
-                    }
                     break;
                 default:
Index: trunk/src/org/openstreetmap/josm/io/imagery/ImageryReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/imagery/ImageryReader.java	(revision 4431)
+++ trunk/src/org/openstreetmap/josm/io/imagery/ImageryReader.java	(revision 4432)
@@ -244,5 +244,4 @@
                             } else {
                                 entry.setDefaultMaxZoom(val);
-                                entry.setMaxZoom(val);
                             }
                         }
Index: trunk/src/org/openstreetmap/josm/io/imagery/WMSGrabber.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/imagery/WMSGrabber.java	(revision 4431)
+++ trunk/src/org/openstreetmap/josm/io/imagery/WMSGrabber.java	(revision 4432)
@@ -47,14 +47,11 @@
 
     protected String baseURL;
-    private final boolean urlWithPatterns;
-    private List<String> serverProjections;
+    private ImageryInfo info;
     private Map<String, String> props = new HashMap<String, String>();
 
     public WMSGrabber(MapView mv, WMSLayer layer) {
         super(mv, layer);
-        this.baseURL = layer.getInfo().getUrl();
-        this.serverProjections = layer.getServerProjections();
-        /* URL containing placeholders? */
-        urlWithPatterns = ImageryInfo.isUrlWithPatterns(baseURL);
+        this.info = layer.getInfo();
+        this.baseURL = info.getUrl();
         if(layer.getInfo().getCookies() != null && !layer.getInfo().getCookies().equals("")) {
             props.put("Cookie", layer.getInfo().getCookies());
@@ -94,27 +91,5 @@
             int wi, int ht) throws MalformedURLException {
         String myProj = Main.getProjection().toCode();
-        String srs = "";
-        boolean useepsg = false;
-        // FIXME: Non-Pattern format should be dropped in future
-        try
-        {
-            Matcher m = Pattern.compile(".*SRS=([a-z0-9:]+).*", Pattern.CASE_INSENSITIVE).matcher(baseURL.toUpperCase());
-            if(m.matches())
-            {
-                if(m.group(1).equals("EPSG:4326") && Main.getProjection() instanceof Mercator)
-                    useepsg = true;
-            } else if((Main.getProjection() instanceof Mercator) && !serverProjections.contains(myProj)) {
-                useepsg = true;
-                srs ="&srs=EPSG:4326";
-            } else {
-                srs ="&srs="+myProj;
-            }
-        }
-        catch(Exception ex)
-        {
-        }
-
-        if(useepsg) // don't use mercator code directly
-        {
+        if((Main.getProjection() instanceof Mercator) && !info.getServerProjections().contains(myProj)) {
             LatLon sw = Main.getProjection().eastNorth2latlon(new EastNorth(w, s));
             LatLon ne = Main.getProjection().eastNorth2latlon(new EastNorth(e, n));
@@ -126,13 +101,9 @@
         }
 
-        String str = baseURL;
-        String bbox = latLonFormat.format(w) + ","
-        + latLonFormat.format(s) + ","
-        + latLonFormat.format(e) + ","
-        + latLonFormat.format(n);
-
-        if (urlWithPatterns) {
-            str = str.replaceAll("\\{proj(\\([^})]+\\))?\\}", myProj)
-            .replaceAll("\\{bbox\\}", bbox)
+        return new URL(baseURL.replaceAll("\\{proj(\\([^})]+\\))?\\}", myProj)
+            .replaceAll("\\{bbox\\}", latLonFormat.format(w) + ","
+                + latLonFormat.format(s) + ","
+                + latLonFormat.format(e) + ","
+                + latLonFormat.format(n))
             .replaceAll("\\{w\\}", latLonFormat.format(w))
             .replaceAll("\\{s\\}", latLonFormat.format(s))
@@ -140,68 +111,6 @@
             .replaceAll("\\{n\\}", latLonFormat.format(n))
             .replaceAll("\\{width\\}", String.valueOf(wi))
-            .replaceAll("\\{height\\}", String.valueOf(ht));
-        } else {
-            str += "bbox=" + bbox
-                    + srs
-                    + "&width=" + wi + "&height=" + ht;
-            if (!(baseURL.endsWith("&") || baseURL.endsWith("?"))) {
-                System.out.println(tr("Warning: The base URL ''{0}'' for a WMS service doesn''t have a trailing ''&'' or a trailing ''?''.", baseURL));
-                System.out.println(tr("Warning: Fetching WMS tiles is likely to fail. Please check you preference settings."));
-                System.out.println(tr("Warning: The complete URL is ''{0}''.", str));
-            }
-        }
-        return new URL(str.replace(" ", "%20"));
-    }
-
-    static public ArrayList<String> getServerProjections(String baseURL, Boolean warn)
-    {
-        ArrayList<String> serverProjections = new ArrayList<String>();
-        boolean hasepsg = false;
-        
-        // FIXME: Non-Pattern format should be dropped in future
-        try
-        {
-            Matcher m = Pattern.compile(".*\\{PROJ\\(([^)}]+)\\)\\}.*").matcher(baseURL.toUpperCase());
-            if(m.matches())
-            {
-                for(String p : m.group(1).split(","))
-                {
-                    serverProjections.add(p);
-                    if(p.equals("EPSG:4326"))
-                        hasepsg = true;
-                }
-            }
-            else
-            {
-                m = Pattern.compile(".*SRS=([a-z0-9:]+).*", Pattern.CASE_INSENSITIVE).matcher(baseURL.toUpperCase());
-                if(m.matches())
-                {
-                    serverProjections.add(m.group(1));
-                    if(m.group(1).equals("EPSG:4326"))
-                        hasepsg = true;
-                }
-                /* TODO: here should be an "else" code checking server capabilities */
-            }
-        }
-        catch(Exception e)
-        {
-        }
-        if(serverProjections.isEmpty())
-            return null;
-        if(warn)
-        {
-            String myProj = Main.getProjection().toCode().toUpperCase();
-            if(!serverProjections.contains(myProj) &&
-            !(Main.getProjection() instanceof Mercator && serverProjections.contains("EPSG:4326")))
-            {
-                JOptionPane.showMessageDialog(Main.parent,
-                        tr("The projection ''{0}'' in URL and current projection ''{1}'' mismatch.\n"
-                                + "This may lead to wrong coordinates.",
-                                serverProjections.get(0), myProj),
-                                tr("Warning"),
-                                JOptionPane.WARNING_MESSAGE);
-            }
-        }
-        return serverProjections;
+            .replaceAll("\\{height\\}", String.valueOf(ht))
+            .replace(" ", "%20"));
     }
 
