Index: /trunk/data/maps.xsd
===================================================================
--- /trunk/data/maps.xsd	(revision 13732)
+++ /trunk/data/maps.xsd	(revision 13733)
@@ -108,4 +108,16 @@
             <!-- TODO: find an easy way to validate projections codes -->
             <xs:element name="code" minOccurs="0" maxOccurs="unbounded" type="xs:string" />
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="defaultLayers">
+        <xs:sequence>
+            <xs:element name="layer" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:attribute name="name" type="xs:string" use="optional" />
+                    <xs:attribute name="style" type="xs:string" use="optional" />
+                    <xs:attribute name="tileMatrixSet" type="xs:string" use="optional" />
+                </xs:complexType>
+            </xs:element>
         </xs:sequence>
     </xs:complexType>
@@ -713,6 +725,17 @@
                             <!-- old unused feature, ignored -->
                             <xs:element name="epsg4326to3857Supported" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+                            <xs:element name="defaultLayers" type="tns:defaultLayers" minOccurs="0" maxOccurs="1" />
+                            <xs:element name="custom-http-header" minOccurs="0" maxOccurs="unbounded">
+                                <xs:complexType>
+                                    <xs:attribute name="header-name" type="xs:string" />
+                                    <xs:attribute name="header-value" type="xs:string" />
+                                </xs:complexType>
+                            </xs:element>
+                            <xs:element name="transparent" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+                            <xs:element name="format" type="xs:string" minOccurs="0" maxOccurs="1"/>
                             <!-- does imagery server supports "/status" and tile re-rendering using "/dirty". Defaults to false. -->
                             <xs:element name="mod-tile-features" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+                            <!--  minimum time in seconds for which tile will be considered valid -->
+                            <xs:element name="minimum-tile-expire" minOccurs="0" maxOccurs="1" type="xs:positiveInteger" />
                         </xs:choice>
                     </xs:sequence>
Index: /trunk/src/org/openstreetmap/josm/actions/AddImageryLayerAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/AddImageryLayerAction.java	(revision 13732)
+++ /trunk/src/org/openstreetmap/josm/actions/AddImageryLayerAction.java	(revision 13733)
@@ -13,7 +13,6 @@
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
+import java.util.stream.Collectors;
 
 import javax.swing.JComboBox;
@@ -27,4 +26,5 @@
 import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryType;
 import org.openstreetmap.josm.data.imagery.WMTSTileSource;
+import org.openstreetmap.josm.data.imagery.WMTSTileSource.WMTSGetCapabilitiesException;
 import org.openstreetmap.josm.gui.ExtendedDialog;
 import org.openstreetmap.josm.gui.layer.AlignImageryPanel;
@@ -34,5 +34,4 @@
 import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.io.imagery.WMSImagery;
-import org.openstreetmap.josm.io.imagery.WMSImagery.LayerDetails;
 import org.openstreetmap.josm.io.imagery.WMSImagery.WMSGetCapabilitiesException;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
@@ -96,17 +95,24 @@
             case WMS_ENDPOINT:
                 // convert to WMS type
-                return getWMSLayerInfo(info);
+                if (info.getDefaultLayers() == null || info.getDefaultLayers().isEmpty()) {
+                    return getWMSLayerInfo(info);
+                } else {
+                    return info;
+                }
             case WMTS:
                 // specify which layer to use
-                DefaultLayer layerId = new WMTSTileSource(info).userSelectLayer();
-                if (layerId != null) {
-                    ImageryInfo copy = new ImageryInfo(info);
-                    Collection<DefaultLayer> defaultLayers = new ArrayList<>(1);
-                    defaultLayers.add(layerId);
-                    copy.setDefaultLayers(defaultLayers);
-                    return copy;
-                }
-                // layer not selected - refuse to add
-                return null;
+                if (info.getDefaultLayers() == null || info.getDefaultLayers().isEmpty()) {
+                    DefaultLayer layerId = new WMTSTileSource(info).userSelectLayer();
+                    if (layerId != null) {
+                        ImageryInfo copy = new ImageryInfo(info);
+                        List<DefaultLayer> defaultLayers = new ArrayList<>(1);
+                        defaultLayers.add(layerId);
+                        copy.setDefaultLayers(defaultLayers);
+                        return copy;
+                    }
+                    return null;
+                } else {
+                    return info;
+                }
             default:
                 return info;
@@ -130,4 +136,10 @@
             }
             Logging.log(Logging.LEVEL_ERROR, "Could not parse WMS layer list. Incoming data:\n"+ex.getIncomingData(), ex);
+        } catch (WMTSGetCapabilitiesException e) {
+            if (!GraphicsEnvironment.isHeadless()) {
+                JOptionPane.showMessageDialog(Main.parent, tr("Could not parse WMTS layer list."),
+                        tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
+            }
+            Logging.log(Logging.LEVEL_ERROR, "Could not parse WMTS layer list.", e);
         }
         return null;
@@ -166,45 +178,68 @@
      */
     protected static ImageryInfo getWMSLayerInfo(ImageryInfo info) throws IOException, WMSGetCapabilitiesException {
-        CheckParameterUtil.ensureThat(ImageryType.WMS_ENDPOINT.equals(info.getImageryType()), "wms_endpoint imagery type expected");
-
-        final WMSImagery wms = new WMSImagery();
-        wms.attemptGetCapabilities(info.getUrl());
-
-        final WMSLayerTree tree = new WMSLayerTree();
-        tree.updateTree(wms);
-        List<String> wmsFormats = wms.getFormats();
-        final JComboBox<String> formats = new JComboBox<>(wmsFormats.toArray(new String[0]));
-        formats.setSelectedItem(wms.getPreferredFormats());
-        formats.setToolTipText(tr("Select image format for WMS layer"));
-
-        if (!GraphicsEnvironment.isHeadless() && 1 != new SelectWmsLayersDialog(tree, formats).showDialog().getValue()) {
-            return null;
-        }
-
-        final String url = wms.buildGetMapUrl(
-                tree.getSelectedLayers(), (String) formats.getSelectedItem());
-        Set<String> supportedCrs = new HashSet<>();
-        boolean first = true;
-        StringBuilder layersString = new StringBuilder();
-        for (LayerDetails layer: tree.getSelectedLayers()) {
-            if (first) {
-                supportedCrs.addAll(layer.getProjections());
-                first = false;
-            }
-            layersString.append(layer.name);
-            layersString.append(", ");
-            supportedCrs.retainAll(layer.getProjections());
-        }
-
-        // copy all information from WMS
-        ImageryInfo ret = new ImageryInfo(info);
-        // and update according to user choice
-        ret.setUrl(url);
-        ret.setImageryType(ImageryType.WMS);
-        if (layersString.length() > 2) {
-            ret.setName(ret.getName() + ' ' + layersString.substring(0, layersString.length() - 2));
-        }
-        ret.setServerProjections(supportedCrs);
-        return ret;
+        try {
+            CheckParameterUtil.ensureThat(ImageryType.WMS_ENDPOINT.equals(info.getImageryType()), "wms_endpoint imagery type expected");
+            final WMSImagery wms = new WMSImagery(info.getUrl());
+
+            final WMSLayerTree tree = new WMSLayerTree();
+            tree.updateTree(wms);
+
+            Collection<String> wmsFormats = wms.getFormats();
+            final JComboBox<String> formats = new JComboBox<>(wmsFormats.toArray(new String[wmsFormats.size()]));
+            formats.setSelectedItem(wms.getPreferredFormat());
+            formats.setToolTipText(tr("Select image format for WMS layer"));
+
+            if (!GraphicsEnvironment.isHeadless()) {
+                if (1 != new ExtendedDialog(Main.parent, tr("Select WMS layers"), new String[]{tr("Add layers"), tr("Cancel")}) { {
+                    final JScrollPane scrollPane = new JScrollPane(tree.getLayerTree());
+                    scrollPane.setPreferredSize(new Dimension(400, 400));
+                    final JPanel panel = new JPanel(new GridBagLayout());
+                    panel.add(scrollPane, GBC.eol().fill());
+                    panel.add(formats, GBC.eol().fill(GBC.HORIZONTAL));
+                    setContent(panel);
+                } }.showDialog().getValue()) {
+                    return null;
+                }
+            }
+
+            final String url = wms.buildGetMapUrl(
+                    tree.getSelectedLayers().stream().map(x -> x.getName()).collect(Collectors.toList()),
+                    (List<String>) null,
+                    (String) formats.getSelectedItem(),
+                    true // TODO: ask the user if (s)he wants transparent layer
+                    );
+
+            String selectedLayers = tree.getSelectedLayers().stream()
+                    .map(x -> x.getName())
+                    .collect(Collectors.joining(", "));
+            ImageryInfo ret = new ImageryInfo(info.getName() + selectedLayers,
+                    url,
+                    "wms",
+                    info.getEulaAcceptanceRequired(),
+                    info.getCookies());
+
+            ret.setServerProjections(wms.getServerProjections(tree.getSelectedLayers()));
+
+            return ret;
+        } catch (MalformedURLException ex) {
+            if (!GraphicsEnvironment.isHeadless()) {
+                JOptionPane.showMessageDialog(Main.parent, tr("Invalid service URL."),
+                        tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
+            }
+            Logging.log(Logging.LEVEL_ERROR, ex);
+        } catch (IOException ex) {
+            if (!GraphicsEnvironment.isHeadless()) {
+                JOptionPane.showMessageDialog(Main.parent, tr("Could not retrieve WMS layer list."),
+                        tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
+            }
+            Logging.log(Logging.LEVEL_ERROR, ex);
+        } catch (WMSGetCapabilitiesException ex) {
+            if (!GraphicsEnvironment.isHeadless()) {
+                JOptionPane.showMessageDialog(Main.parent, tr("Could not parse WMS layer list."),
+                        tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
+            }
+            Logging.log(Logging.LEVEL_ERROR, "Could not parse WMS layer list. Incoming data:\n"+ex.getIncomingData(), ex);
+        }
+        return null;
     }
 
Index: /trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java	(revision 13732)
+++ /trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java	(revision 13733)
@@ -21,4 +21,5 @@
 import org.apache.commons.jcs.engine.behavior.ICacheElement;
 import org.openstreetmap.josm.data.cache.ICachedLoaderListener.LoadResult;
+import org.openstreetmap.josm.data.imagery.TileJobOptions;
 import org.openstreetmap.josm.data.preferences.IntegerProperty;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
@@ -93,36 +94,31 @@
     private Runnable finishTask;
     private boolean force;
+    private long minimumExpiryTime;
 
     /**
      * @param cache cache instance that we will work on
-     * @param headers HTTP headers to be sent together with request
-     * @param readTimeout when connecting to remote resource
-     * @param connectTimeout when connecting to remote resource
+     * @param options options of the request
      * @param downloadJobExecutor that will be executing the jobs
      */
     public JCSCachedTileLoaderJob(ICacheAccess<K, V> cache,
-            int connectTimeout, int readTimeout,
-            Map<String, String> headers,
+            TileJobOptions options,
             ThreadPoolExecutor downloadJobExecutor) {
         CheckParameterUtil.ensureParameterNotNull(cache, "cache");
         this.cache = cache;
         this.now = System.currentTimeMillis();
-        this.connectTimeout = connectTimeout;
-        this.readTimeout = readTimeout;
-        this.headers = headers;
+        this.connectTimeout = options.getConnectionTimeout();
+        this.readTimeout = options.getReadTimeout();
+        this.headers = options.getHeaders();
         this.downloadJobExecutor = downloadJobExecutor;
+        this.minimumExpiryTime = TimeUnit.SECONDS.toMillis(options.getMinimumExpiryTime());
     }
 
     /**
      * @param cache cache instance that we will work on
-     * @param headers HTTP headers to be sent together with request
-     * @param readTimeout when connecting to remote resource
-     * @param connectTimeout when connecting to remote resource
+     * @param options of the request
      */
     public JCSCachedTileLoaderJob(ICacheAccess<K, V> cache,
-            int connectTimeout, int readTimeout,
-            Map<String, String> headers) {
-        this(cache, connectTimeout, readTimeout,
-                headers, DEFAULT_DOWNLOAD_JOB_DISPATCHER);
+            TileJobOptions options) {
+        this(cache, options, DEFAULT_DOWNLOAD_JOB_DISPATCHER);
     }
 
@@ -278,5 +274,5 @@
             // put a limit to the expire time (some servers send a value
             // that is too large)
-            expires = Math.min(expires, attributes.getCreateTime() + EXPIRE_TIME_SERVER_LIMIT);
+            expires = Math.min(expires, attributes.getCreateTime() + Math.max(EXPIRE_TIME_SERVER_LIMIT, minimumExpiryTime));
             if (now > expires) {
                 Logging.debug("JCS - Object {0} has expired -> valid to {1}, now is: {2}",
@@ -285,9 +281,9 @@
             }
         } else if (attributes.getLastModification() > 0 &&
-                now - attributes.getLastModification() > DEFAULT_EXPIRE_TIME) {
+                now - attributes.getLastModification() > Math.max(DEFAULT_EXPIRE_TIME, minimumExpiryTime)) {
             // check by file modification date
             Logging.debug("JCS - Object has expired, maximum file age reached {0}", getUrlNoException());
             return false;
-        } else if (now - attributes.getCreateTime() > DEFAULT_EXPIRE_TIME) {
+        } else if (now - attributes.getCreateTime() > Math.max(DEFAULT_EXPIRE_TIME, minimumExpiryTime)) {
             Logging.debug("JCS - Object has expired, maximum time since object creation reached {0}", getUrlNoException());
             return false;
@@ -330,4 +326,7 @@
                 // and the server answers with a HTTP 304 = "Not Modified"
                 Logging.debug("JCS - If-Modified-Since/ETag test: local version is up to date: {0}", getUrl());
+                // update cache attributes
+                attributes = parseHeaders(urlConn);
+                cache.put(getCacheKey(), cacheData, attributes);
                 return true;
             } else if (isObjectLoadable() // we have an object in cache, but we haven't received 304 response code
@@ -453,7 +452,10 @@
                 Logging.trace(e);
             }
-        }
-
-        ret.setExpirationTime(lng);
+            if (lng.equals(0L)) {
+                lng = System.currentTimeMillis() + DEFAULT_EXPIRE_TIME;
+            }
+        }
+
+        ret.setExpirationTime(Math.max(minimumExpiryTime + System.currentTimeMillis(), lng));
         ret.setLastModification(now);
         ret.setEtag(urlConn.getHeaderField("ETag"));
@@ -480,6 +482,12 @@
         final HttpClient.Response urlConn = getRequest("HEAD", false).connect();
         long lastModified = urlConn.getLastModified();
-        return (attributes.getEtag() != null && attributes.getEtag().equals(urlConn.getHeaderField("ETag"))) ||
+        boolean ret = (attributes.getEtag() != null && attributes.getEtag().equals(urlConn.getHeaderField("ETag"))) ||
                 (lastModified != 0 && lastModified <= attributes.getLastModification());
+        if (ret) {
+            // update attributes
+            attributes = parseHeaders(urlConn);
+            cache.put(getCacheKey(), cacheData, attributes);
+        }
+        return ret;
     }
 
Index: /trunk/src/org/openstreetmap/josm/data/imagery/AbstractWMSTileSource.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/imagery/AbstractWMSTileSource.java	(revision 13732)
+++ /trunk/src/org/openstreetmap/josm/data/imagery/AbstractWMSTileSource.java	(revision 13733)
@@ -3,4 +3,8 @@
 
 import java.awt.Point;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
+import java.util.Locale;
 
 import org.openstreetmap.gui.jmapviewer.Projected;
@@ -24,4 +28,6 @@
 public abstract class AbstractWMSTileSource extends TMSTileSource {
 
+    static final NumberFormat LATLON_FORMAT = new DecimalFormat("###0.0000000", new DecimalFormatSymbols(Locale.US));
+
     private EastNorth anchorPosition;
     private int[] tileXMin;
@@ -209,3 +215,24 @@
         return this.tileProjection.toCode();
     }
+
+    protected String getBbox(int zoom, int tilex, int tiley, boolean switchLatLon) {
+        EastNorth nw = getTileEastNorth(tilex, tiley, zoom);
+        EastNorth se = getTileEastNorth(tilex + 1, tiley + 1, zoom);
+
+        double w = nw.getX();
+        double n = nw.getY();
+
+        double s = se.getY();
+        double e = se.getX();
+
+        return (
+                switchLatLon ?
+                        String.format("%s,%s,%s,%s",
+                                LATLON_FORMAT.format(s), LATLON_FORMAT.format(w), LATLON_FORMAT.format(n), LATLON_FORMAT.format(e))
+                        :
+                        String.format("%s,%s,%s,%s",
+                                LATLON_FORMAT.format(w), LATLON_FORMAT.format(s), LATLON_FORMAT.format(e), LATLON_FORMAT.format(n))
+
+                );
+    }
 }
Index: /trunk/src/org/openstreetmap/josm/data/imagery/CachedTileLoaderFactory.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/imagery/CachedTileLoaderFactory.java	(revision 13732)
+++ /trunk/src/org/openstreetmap/josm/data/imagery/CachedTileLoaderFactory.java	(revision 13733)
@@ -44,7 +44,6 @@
                     TileLoaderListener.class,
                     ICacheAccess.class,
-                    int.class,
-                    int.class,
-                    Map.class);
+                    TileJobOptions.class
+                    );
         } catch (NoSuchMethodException | SecurityException e) {
             Logging.log(Logging.LEVEL_WARN, "Unable to initialize cache tile loader factory", e);
@@ -64,5 +63,5 @@
 
     @Override
-    public TileLoader makeTileLoader(TileLoaderListener listener, Map<String, String> inputHeaders) {
+    public TileLoader makeTileLoader(TileLoaderListener listener, Map<String, String> inputHeaders, long minimumExpiryTime) {
         Map<String, String> headers = new ConcurrentHashMap<>();
         headers.put("User-Agent", Version.getInstance().getFullAgentString());
@@ -72,18 +71,21 @@
 
         return getLoader(listener, cache,
-                (int) TimeUnit.SECONDS.toMillis(Config.getPref().getInt("socket.timeout.connect", 15)),
-                (int) TimeUnit.SECONDS.toMillis(Config.getPref().getInt("socket.timeout.read", 30)),
-                headers);
+                new TileJobOptions(
+                        (int) TimeUnit.SECONDS.toMillis(Config.getPref().getInt("socket.timeout.connect", 15)),
+                        (int) TimeUnit.SECONDS.toMillis(Config.getPref().getInt("socket.timeout.read", 30)),
+                        headers,
+                        minimumExpiryTime
+                        )
+                );
     }
 
     protected TileLoader getLoader(TileLoaderListener listener, ICacheAccess<String, BufferedImageCacheEntry> cache,
-            int connectTimeout, int readTimeout, Map<String, String> headers) {
+            TileJobOptions options) {
         try {
             return tileLoaderConstructor.newInstance(
                     listener,
                     cache,
-                    connectTimeout,
-                    readTimeout,
-                    headers);
+                    options
+                    );
         } catch (IllegalArgumentException e) {
             Logging.warn(e);
Index: /trunk/src/org/openstreetmap/josm/data/imagery/DefaultLayer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/imagery/DefaultLayer.java	(revision 13732)
+++ /trunk/src/org/openstreetmap/josm/data/imagery/DefaultLayer.java	(revision 13733)
@@ -1,4 +1,12 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.data.imagery;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+
+import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryType;
 
 /**
@@ -12,13 +20,22 @@
  */
 public class DefaultLayer {
-
-    protected String layerName;
+    private final String layerName;
+    private final String tileMatrixSet;
+    private final String style;
 
     /**
      * Constructor
-     * @param layerName that is the DefaultLayer
+     * @param imageryType for which this layer is defined
+     * @param layerName as returned by getIdentifier for WMTS and getName for WMS
+     * @param style of the layer
+     * @param tileMatrixSet only for WMTS - tileMatrixSet to use
      */
-    public DefaultLayer(String layerName) {
-        this.layerName = layerName;
+    public DefaultLayer(ImageryType imageryType, String layerName, String style, String tileMatrixSet) {
+        this.layerName = layerName == null ? "" : layerName;
+        this.style = style == null ? "" : style;
+        if (!imageryType.equals(ImageryType.WMTS) && !(tileMatrixSet == null || "".equals(tileMatrixSet))) {
+            throw new IllegalArgumentException(tr("{0} imagery has tileMatrixSet defined to: {1}", imageryType, tileMatrixSet));
+        }
+        this.tileMatrixSet = tileMatrixSet == null ? "" : tileMatrixSet;
     }
 
@@ -30,3 +47,37 @@
     }
 
+    /**
+     * @return default tileMatrixSet. Only usable for WMTS
+     */
+    public String getTileMatrixSet() {
+        return tileMatrixSet;
+    }
+
+    /**
+     * @return style for this WMS / WMTS layer to use
+     */
+    public String getStyle() {
+        return style;
+    }
+
+    /**
+     * @return JSON representation of the default layer object
+     */
+    public JsonObject toJson() {
+        JsonObjectBuilder ret = Json.createObjectBuilder();
+        ret.add("layerName", layerName);
+        ret.add("style", style);
+        ret.add("tileMatrixSet", tileMatrixSet);
+        return ret.build();
+    }
+
+    /**
+     * Factory method creating DefaultLayer from JSON objects
+     * @param o serialized DefaultLayer object
+     * @param type of ImageryType serialized
+     * @return DefaultLayer instance based on JSON object
+     */
+    public static DefaultLayer fromJson(JsonObject o, ImageryType type) {
+        return new DefaultLayer(type, o.getString("layerName"), o.getString("style"), o.getString("tileMatrixSet"));
+    }
 }
Index: /trunk/src/org/openstreetmap/josm/data/imagery/ImageryInfo.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/imagery/ImageryInfo.java	(revision 13732)
+++ /trunk/src/org/openstreetmap/josm/data/imagery/ImageryInfo.java	(revision 13733)
@@ -5,4 +5,5 @@
 
 import java.awt.Image;
+import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -15,8 +16,13 @@
 import java.util.Set;
 import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.stream.JsonCollectors;
 import javax.swing.ImageIcon;
 
@@ -218,7 +224,17 @@
     private boolean isGeoreferenceValid;
     /** which layers should be activated by default on layer addition. **/
-    private Collection<DefaultLayer> defaultLayers = Collections.emptyList();
-    // when adding a field, also adapt the ImageryInfo(ImageryInfo)
-    // and ImageryInfo(ImageryPreferenceEntry) constructor, equals method, and ImageryPreferenceEntry
+    private List<DefaultLayer> defaultLayers = new ArrayList<>();
+    /** HTTP headers **/
+    private Map<String, String> customHttpHeaders = new ConcurrentHashMap<>();
+    /** Should this map be transparent **/
+    private boolean transparent = true;
+    private int minimumTileExpire = (int) TimeUnit.MILLISECONDS.toSeconds(TMSCachedTileLoaderJob.MINIMUM_EXPIRES.get());
+    /** when adding a field, also adapt the:
+     * {@link #ImageryPreferenceEntry ImageryPreferenceEntry object}
+     * {@link #ImageryPreferenceEntry#ImageryPreferenceEntry(ImageryInfo) ImageryPreferenceEntry constructor}
+     * {@link #ImageryInfo(ImageryPreferenceEntry) ImageryInfo constructor}
+     * {@link #ImageryInfo(ImageryInfo) ImageryInfo constructor}
+     * {@link #equalsPref(ImageryPreferenceEntry) equalsPref method}
+     **/
 
     /**
@@ -258,6 +274,8 @@
         @StructEntry boolean modTileFeatures;
         @StructEntry boolean overlay;
-        // TODO: disabled until change of layers is implemented
-        // @StructEntry String default_layers;
+        @StructEntry String default_layers;
+        @StructEntry Map<String, String> customHttpHeaders;
+        @StructEntry boolean transparent;
+        @StructEntry int minimumTileExpire;
 
         /**
@@ -308,5 +326,7 @@
                 }
             }
-            projections = i.serverProjections.stream().collect(Collectors.joining(","));
+            if (!i.serverProjections.isEmpty()) {
+                projections = i.serverProjections.stream().collect(Collectors.joining(","));
+            }
             if (i.noTileHeaders != null && !i.noTileHeaders.isEmpty()) {
                 noTileHeaders = new MultiMap<>(i.noTileHeaders);
@@ -325,6 +345,10 @@
             valid_georeference = i.isGeoreferenceValid();
             modTileFeatures = i.isModTileFeatures();
-            // TODO disabled until change of layers is implemented
-            // default_layers = i.defaultLayers.stream().collect(Collectors.joining(","));
+            if (!i.defaultLayers.isEmpty()) {
+                default_layers = i.defaultLayers.stream().map(x -> x.toJson()).collect(JsonCollectors.toJsonArray()).toString();
+            }
+            customHttpHeaders = i.customHttpHeaders;
+            transparent = i.isTransparent();
+            minimumTileExpire = i.minimumTileExpire;
         }
 
@@ -468,6 +492,14 @@
         isGeoreferenceValid = e.valid_georeference;
         modTileFeatures = e.modTileFeatures;
-        // TODO disabled until change of layers is implemented
-        // defaultLayers = Arrays.asList(e.default_layers.split(","));
+        if (e.default_layers != null) {
+            defaultLayers = Json.createReader(new StringReader(e.default_layers)).
+                    readArray().
+                    stream().
+                    map(x -> DefaultLayer.fromJson((JsonObject) x, imageryType)).
+                    collect(Collectors.toList());
+        }
+        customHttpHeaders = e.customHttpHeaders;
+        transparent = e.transparent;
+        minimumTileExpire = e.minimumTileExpire;
     }
 
@@ -514,4 +546,7 @@
         this.isGeoreferenceValid = i.isGeoreferenceValid;
         this.defaultLayers = i.defaultLayers;
+        this.customHttpHeaders = i.customHttpHeaders;
+        this.transparent = i.transparent;
+        this.minimumTileExpire = i.minimumTileExpire;
     }
 
@@ -565,5 +600,8 @@
                 Objects.equals(this.noTileChecksums, other.noTileChecksums) &&
                 Objects.equals(this.metadataHeaders, other.metadataHeaders) &&
-                Objects.equals(this.defaultLayers, other.defaultLayers);
+                Objects.equals(this.defaultLayers, other.defaultLayers) &&
+                Objects.equals(this.customHttpHeaders, other.customHttpHeaders) &&
+                Objects.equals(this.transparent, other.transparent) &&
+                Objects.equals(this.minimumTileExpire, other.minimumTileExpire);
         // CHECKSTYLE.ON: BooleanExpressionComplexity
     }
@@ -1372,5 +1410,5 @@
      * @return Collection of the layer names
      */
-    public Collection<DefaultLayer> getDefaultLayers() {
+    public List<DefaultLayer> getDefaultLayers() {
         return defaultLayers;
     }
@@ -1380,11 +1418,53 @@
      * @param layers set the list of default layers
      */
-    public void setDefaultLayers(Collection<DefaultLayer> layers) {
-        if (ImageryType.WMTS.equals(this.imageryType)) {
-            CheckParameterUtil.ensureThat(layers == null ||
-                    layers.isEmpty() ||
-                    layers.iterator().next() instanceof WMTSDefaultLayer, "Incorrect default layer");
-        }
+    public void setDefaultLayers(List<DefaultLayer> layers) {
         this.defaultLayers = layers;
     }
+
+    /**
+     * Returns custom HTTP headers that should be sent with request towards imagery provider
+     * @return headers
+     */
+    public Map<String, String> getCustomHttpHeaders() {
+        return customHttpHeaders;
+    }
+
+    /**
+     * Sets custom HTTP headers that should be sent with request towards imagery provider
+     * @param customHttpHeaders
+     */
+    public void setCustomHttpHeaders(Map<String, String> customHttpHeaders) {
+        this.customHttpHeaders = customHttpHeaders;
+    }
+
+    /**
+     * @return should this imagery be transparent
+     */
+    public boolean isTransparent() {
+        return transparent;
+    }
+
+    /**
+     *
+     * @param transparent set to true if imagery should be transparent
+     */
+    public void setTransparent(boolean transparent) {
+        this.transparent = transparent;
+    }
+
+    /**
+     * @return minimum tile expiration in seconds
+     */
+    public int getMinimumTileExpire() {
+        return minimumTileExpire;
+    }
+
+    /**
+     * Sets minimum tile expiration in seconds
+     * @param minimumTileExpire
+     */
+    public void setMinimumTileExpire(int minimumTileExpire) {
+        this.minimumTileExpire = minimumTileExpire;
+
+    }
 }
Index: /trunk/src/org/openstreetmap/josm/data/imagery/LayerDetails.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/imagery/LayerDetails.java	(revision 13733)
+++ /trunk/src/org/openstreetmap/josm/data/imagery/LayerDetails.java	(revision 13733)
@@ -0,0 +1,209 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.imagery;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Stream;
+
+import org.openstreetmap.josm.data.Bounds;
+
+/**
+ * The details of a layer of this WMS server.
+ */
+public class LayerDetails {
+    private Map<String, String> styles = new ConcurrentHashMap<>(); // name -> title
+    private Collection<String> crs = new ArrayList<>();
+    /**
+     * The layer name (WMS {@code Title})
+     */
+    private String title;
+    /**
+     * The layer name (WMS {@code Name})
+     */
+    private String name;
+    /**
+     * The layer abstract (WMS {@code Abstract})
+     * @since 13199
+     */
+    private String abstr;
+    private LayerDetails parentLayer;
+    private Bounds bounds;
+    private List<LayerDetails> children = new ArrayList<>();
+
+    /**
+     * Constructor pointing to parent layer. Set to null if this is topmost layer.
+     * This is needed to properly handle layer attributes inheritance.
+     *
+     * @param parentLayer
+     */
+    public LayerDetails(LayerDetails parentLayer) {
+        this.parentLayer = parentLayer;
+    }
+
+    /**
+     * @return projections that are supported by this layer
+     */
+    public Collection<String> getCrs() {
+        Collection<String> ret = new ArrayList<>();
+        if (parentLayer != null) {
+            ret.addAll(parentLayer.getCrs());
+        }
+        ret.addAll(crs);
+        return crs;
+    }
+
+    /**
+     *
+     * @return styles defined for this layer
+     */
+    public Map<String, String> getStyles() {
+        Map<String, String> ret = new ConcurrentHashMap<>();
+        if (parentLayer != null) {
+            ret.putAll(parentLayer.getStyles());
+        }
+        ret.putAll(styles);
+        return ret;
+    }
+
+    /**
+     * @see LayerDetails#getName()
+     * @return title "Human readable" title of this layer
+     */
+    public String getTitle() {
+        return title;
+    }
+
+    /**
+     * @see LayerDetails#getName()
+     * @param title set title of this layer
+     */
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    /**
+     *
+     * Citation from OGC WMS specification (WMS 1.3.0):
+     * > A number of elements have both a <Name> and a <Title>. The Name is a text string used for machine-to-machine
+     * > communication while the Title is for the benefit of humans. For example, a dataset might have the descriptive Title
+     * > “Maximum Atmospheric Temperature” and be requested using the abbreviated Name “ATMAX”.
+     *
+     * And second citation:
+     * > If, and only if, a layer has a <Name>, then it is a map layer that can be requested by using that Name in the
+     * > LAYERS parameter of a GetMap request. A Layer that contains a <Name> element is referred to as a “named
+     * > layer” in this International Standard. If the layer has a Title but no Name, then that layer is only a category title for
+     * > all the layers nested within.
+     * @return name of this layer
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * @see LayerDetails#getName()
+     * @param name sets the name of this Layer
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Add style to list of styles defined by this layer
+     * @param name machine-to-machine name of this style
+     * @param title human readable title of this style
+     */
+    public void addStyle(String name, String title) {
+        this.styles.put(name, title);
+    }
+
+    /**
+     * Add projection supported by this layer
+     * @param crs projection code
+     */
+    public void addCrs(String crs) {
+        this.crs.add(crs);
+    }
+
+    /**
+     *
+     * @return bounds within layer might be queried
+     */
+    public Bounds getBounds() {
+        return bounds;
+    }
+
+    /**
+     * sets bounds of this layer
+     * @param bounds
+     */
+    public void setBounds(Bounds bounds) {
+        this.bounds = bounds;
+    }
+
+    @Override
+    public String toString() {
+        String baseName = (title == null || title.isEmpty()) ? name : title;
+        return abstr == null || abstr.equalsIgnoreCase(baseName) ? baseName : baseName + " (" + abstr + ')';
+    }
+
+    /**
+     *
+     * @return parent layer for his layer
+     */
+    public LayerDetails getParent() {
+        return parentLayer;
+    }
+
+    /**
+     * sets children layers for this layer
+     * @param children
+     */
+    public void setChildren(List<LayerDetails> children) {
+        this.children = children;
+
+    }
+
+    /**
+     *
+     * @return children layers of this layer
+     */
+    public List<LayerDetails> getChildren() {
+        return children;
+    }
+
+    /**
+     * if user may select this layer (is it possible to request it from server)
+     * @return true if user may select this layer, false if this layer is only grouping other layers
+     */
+    public boolean isSelectable() {
+        return !(name == null || name.isEmpty());
+    }
+
+    /**
+     * @return "Narrative description of the layer"
+     */
+    public String getAbstract() {
+        return abstr;
+    }
+
+    /**
+     * Sets abstract of this layer
+     * @param abstr
+     */
+    public void setAbstract(String abstr) {
+        this.abstr = abstr;
+    }
+
+    /**
+     * @return flattened stream of this layer and its children (as well as recursively children of its children)
+     */
+    public Stream<LayerDetails> flattened() {
+        return Stream.concat(
+                Stream.of(this),
+                getChildren().stream().flatMap(LayerDetails::flattened)
+                );
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoader.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoader.java	(revision 13732)
+++ /trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoader.java	(revision 13733)
@@ -2,5 +2,4 @@
 package org.openstreetmap.josm.data.imagery;
 
-import java.util.Map;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
@@ -27,7 +26,4 @@
 
     protected final ICacheAccess<String, BufferedImageCacheEntry> cache;
-    protected final int connectTimeout;
-    protected final int readTimeout;
-    protected final Map<String, String> headers;
     protected final TileLoaderListener listener;
 
@@ -50,20 +46,17 @@
 
     private ThreadPoolExecutor downloadExecutor = DEFAULT_DOWNLOAD_JOB_DISPATCHER;
+    protected final TileJobOptions options;
 
     /**
      * Constructor
      * @param listener          called when tile loading has finished
-     * @param cache              of the cache
-     * @param connectTimeout    to remote resource
-     * @param readTimeout       to remote resource
-     * @param headers           HTTP headers to be sent along with request
+     * @param cache             of the cache
+     * @param options           tile job options
      */
     public TMSCachedTileLoader(TileLoaderListener listener, ICacheAccess<String, BufferedImageCacheEntry> cache,
-            int connectTimeout, int readTimeout, Map<String, String> headers) {
+           TileJobOptions options) {
         CheckParameterUtil.ensureParameterNotNull(cache, "cache");
         this.cache = cache;
-        this.connectTimeout = connectTimeout;
-        this.readTimeout = readTimeout;
-        this.headers = headers;
+        this.options = options;
         this.listener = listener;
     }
@@ -98,6 +91,10 @@
     @Override
     public TileJob createTileLoaderJob(Tile tile) {
-        return new TMSCachedTileLoaderJob(listener, tile, cache,
-                connectTimeout, readTimeout, headers, getDownloadExecutor());
+        return new TMSCachedTileLoaderJob(
+                listener,
+                tile,
+                cache,
+                options,
+                getDownloadExecutor());
     }
 
Index: /trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java	(revision 13732)
+++ /trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java	(revision 13733)
@@ -44,9 +44,12 @@
  */
 public class TMSCachedTileLoaderJob extends JCSCachedTileLoaderJob<String, BufferedImageCacheEntry> implements TileJob, ICachedLoaderListener {
-    private static final LongProperty MAXIMUM_EXPIRES = new LongProperty("imagery.generic.maximum_expires", TimeUnit.DAYS.toMillis(30));
-    private static final LongProperty MINIMUM_EXPIRES = new LongProperty("imagery.generic.minimum_expires", TimeUnit.HOURS.toMillis(1));
+    /** General maximum expires for tiles. Might be overridden by imagery settings */
+    public static final LongProperty MAXIMUM_EXPIRES = new LongProperty("imagery.generic.maximum_expires", TimeUnit.DAYS.toMillis(30));
+    /** General minimum expires for tiles. Might be overridden by imagery settings */
+    public static final LongProperty MINIMUM_EXPIRES = new LongProperty("imagery.generic.minimum_expires", TimeUnit.HOURS.toMillis(1));
     static final Pattern SERVICE_EXCEPTION_PATTERN = Pattern.compile("(?s).+<ServiceException[^>]*>(.+)</ServiceException>.+");
     protected final Tile tile;
     private volatile URL url;
+    private final TileJobOptions options;
 
     // we need another deduplication of Tile Loader listeners, as for each submit, new TMSCachedTileLoaderJob was created
@@ -59,15 +62,14 @@
      * @param tile to be fetched from cache
      * @param cache object
-     * @param connectTimeout when connecting to remote resource
-     * @param readTimeout when connecting to remote resource
-     * @param headers HTTP headers to be sent together with request
+     * @param options for job (such as http headers, timeouts etc.)
      * @param downloadExecutor that will be executing the jobs
      */
     public TMSCachedTileLoaderJob(TileLoaderListener listener, Tile tile,
             ICacheAccess<String, BufferedImageCacheEntry> cache,
-            int connectTimeout, int readTimeout, Map<String, String> headers,
+            TileJobOptions options,
             ThreadPoolExecutor downloadExecutor) {
-        super(cache, connectTimeout, readTimeout, headers, downloadExecutor);
+        super(cache, options, downloadExecutor);
         this.tile = tile;
+        this.options = options;
         if (listener != null) {
             String deduplicationKey = getCacheKey();
@@ -245,8 +247,8 @@
         // 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() < now + MINIMUM_EXPIRES.get()) {
+        if (ret.getExpirationTime() < now + Math.max(MINIMUM_EXPIRES.get(), options.getMinimumExpiryTime())) {
             ret.setExpirationTime(now + MINIMUM_EXPIRES.get());
         }
-        if (ret.getExpirationTime() > now + MAXIMUM_EXPIRES.get()) {
+        if (ret.getExpirationTime() > now + Math.max(MAXIMUM_EXPIRES.get(), options.getMinimumExpiryTime())) {
             ret.setExpirationTime(now + MAXIMUM_EXPIRES.get());
         }
Index: /trunk/src/org/openstreetmap/josm/data/imagery/TemplatedWMSTileSource.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/imagery/TemplatedWMSTileSource.java	(revision 13732)
+++ /trunk/src/org/openstreetmap/josm/data/imagery/TemplatedWMSTileSource.java	(revision 13733)
@@ -59,4 +59,5 @@
         super(info, tileProjection);
         this.serverProjections = new TreeSet<>(info.getServerProjections());
+        this.headers.putAll(info.getCustomHttpHeaders());
         handleTemplate();
         initProjection();
@@ -109,12 +110,5 @@
             switchLatLon = Main.getProjection().switchXY();
         }
-        String bbox;
-        if (switchLatLon) {
-            bbox = String.format("%s,%s,%s,%s",
-                    LATLON_FORMAT.format(s), LATLON_FORMAT.format(w), LATLON_FORMAT.format(n), LATLON_FORMAT.format(e));
-        } else {
-            bbox = String.format("%s,%s,%s,%s",
-                    LATLON_FORMAT.format(w), LATLON_FORMAT.format(s), LATLON_FORMAT.format(e), LATLON_FORMAT.format(n));
-        }
+        String bbox = getBbox(zoom, tilex, tiley, switchLatLon);
 
         // Using StringBuffer and generic PATTERN_PARAM matcher gives 2x performance improvement over replaceAll
Index: /trunk/src/org/openstreetmap/josm/data/imagery/TileJobOptions.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/imagery/TileJobOptions.java	(revision 13733)
+++ /trunk/src/org/openstreetmap/josm/data/imagery/TileJobOptions.java	(revision 13733)
@@ -0,0 +1,66 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.imagery;
+
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * Class containing all options that are passed from Layer to TileJob
+ *
+ * @author Wiktor Niesiobedzki
+ *
+ */
+public class TileJobOptions {
+
+    final int connectTimeout;
+    final int readTimeout;
+    final Map<String, String> headers;
+    final long minimumExpiryTime;
+
+    /**
+     * Options constructor
+     *
+     * @param connectTimeout in milliseconds
+     * @param readTimeout in milliseconds
+     * @param headers
+     * @param minimumExpiryTime in seconds
+     */
+    public TileJobOptions(int connectTimeout, int readTimeout, Map<String, String> headers, long minimumExpiryTime) {
+        this.connectTimeout = connectTimeout;
+        this.readTimeout = readTimeout;
+        this.headers = Collections.unmodifiableMap(headers == null ? Collections.emptyMap() : headers);
+        this.minimumExpiryTime = minimumExpiryTime;
+    }
+
+    /**
+     *
+     * @return socket connection timeout in milliseconds
+     */
+    public int getConnectionTimeout() {
+        return connectTimeout;
+    }
+
+    /**
+     *
+     * @return socket read timeout in milliseconds
+     */
+    public int getReadTimeout() {
+        return readTimeout;
+    }
+
+    /**
+     *
+     * @return unmodifiable map with headers to be sent to tile server
+     */
+    public Map<String, String> getHeaders() {
+        return headers;
+    }
+
+    /**
+     *
+     * @return minimum cache expire time in seconds for downloaded tiles
+     */
+    public long getMinimumExpiryTime() {
+        return minimumExpiryTime;
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/data/imagery/TileLoaderFactory.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/imagery/TileLoaderFactory.java	(revision 13732)
+++ /trunk/src/org/openstreetmap/josm/data/imagery/TileLoaderFactory.java	(revision 13733)
@@ -19,6 +19,7 @@
      * @param listener that will be notified, when tile has finished loading
      * @param headers that will be sent with requests to TileSource. <code>null</code> indicates none
+     * @param minimumExpiryTime minimum expiry time
      * @return TileLoader that uses both of above
      */
-    TileLoader makeTileLoader(TileLoaderListener listener, Map<String, String> headers);
+    TileLoader makeTileLoader(TileLoaderListener listener, Map<String, String> headers, long minimumExpiryTime);
 }
Index: /trunk/src/org/openstreetmap/josm/data/imagery/WMSCachedTileLoader.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/imagery/WMSCachedTileLoader.java	(revision 13732)
+++ /trunk/src/org/openstreetmap/josm/data/imagery/WMSCachedTileLoader.java	(revision 13733)
@@ -1,6 +1,4 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.data.imagery;
-
-import java.util.Map;
 
 import org.apache.commons.jcs.access.behavior.ICacheAccess;
@@ -35,7 +33,7 @@
      */
     public WMSCachedTileLoader(TileLoaderListener listener, ICacheAccess<String, BufferedImageCacheEntry> cache,
-            int connectTimeout, int readTimeout, Map<String, String> headers) {
+            TileJobOptions options) {
 
-        super(listener, cache, connectTimeout, readTimeout, headers);
+        super(listener, cache, options);
         setDownloadExecutor(TMSCachedTileLoader.getNewThreadPoolExecutor("WMS-downloader-%d", THREAD_LIMIT.get()));
     }
@@ -43,5 +41,5 @@
     @Override
     public TileJob createTileLoaderJob(Tile tile) {
-        return new WMSCachedTileLoaderJob(listener, tile, cache, connectTimeout, readTimeout, headers, getDownloadExecutor());
+        return new WMSCachedTileLoaderJob(listener, tile, cache, options, getDownloadExecutor());
     }
 }
Index: /trunk/src/org/openstreetmap/josm/data/imagery/WMSCachedTileLoaderJob.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/imagery/WMSCachedTileLoaderJob.java	(revision 13732)
+++ /trunk/src/org/openstreetmap/josm/data/imagery/WMSCachedTileLoaderJob.java	(revision 13733)
@@ -2,5 +2,4 @@
 package org.openstreetmap.josm.data.imagery;
 
-import java.util.Map;
 import java.util.concurrent.ThreadPoolExecutor;
 
@@ -23,13 +22,13 @@
      * @param tile to load
      * @param cache to use (get/put)
-     * @param connectTimeout to tile source
-     * @param readTimeout to tile source
-     * @param headers to be sent with request
+     * @param options options for tile job
      * @param downloadExecutor that will execute the download task (if needed)
      */
-    public WMSCachedTileLoaderJob(TileLoaderListener listener, Tile tile,
-            ICacheAccess<String, BufferedImageCacheEntry> cache, int connectTimeout, int readTimeout,
-            Map<String, String> headers, ThreadPoolExecutor downloadExecutor) {
-        super(listener, tile, cache, connectTimeout, readTimeout, headers, downloadExecutor);
+    public WMSCachedTileLoaderJob(TileLoaderListener listener,
+            Tile tile,
+            ICacheAccess<String, BufferedImageCacheEntry> cache,
+            TileJobOptions options,
+            ThreadPoolExecutor downloadExecutor) {
+        super(listener, tile, cache, options, downloadExecutor);
     }
 
Index: /trunk/src/org/openstreetmap/josm/data/imagery/WMSEndpointTileSource.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/imagery/WMSEndpointTileSource.java	(revision 13733)
+++ /trunk/src/org/openstreetmap/josm/data/imagery/WMSEndpointTileSource.java	(revision 13733)
@@ -0,0 +1,101 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.imagery;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import org.openstreetmap.gui.jmapviewer.interfaces.TemplatedTileSource;
+import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryType;
+import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.gui.layer.WMSLayer;
+import org.openstreetmap.josm.io.imagery.WMSImagery;
+import org.openstreetmap.josm.io.imagery.WMSImagery.WMSGetCapabilitiesException;
+import org.openstreetmap.josm.tools.CheckParameterUtil;
+
+/**
+ * Class representing ImageryType.WMS_ENDPOINT tile source.
+ * It differs from standard WMS tile source that this tile source fetches GetCapabilities from server and
+ * uses most of the parameters from there
+ *
+ * @author Wiktor Niesiobedzki
+ *
+ */
+public class WMSEndpointTileSource extends AbstractWMSTileSource implements TemplatedTileSource {
+
+    private final WMSImagery wmsi;
+    private List<DefaultLayer> layers;
+    private String urlPattern;
+    private static final Pattern PATTERN_PARAM  = Pattern.compile("\\{([^}]+)\\}");
+    private final Map<String, String> headers = new ConcurrentHashMap<>();
+
+    /**
+     * Create WMSEndpointTileSource tile source
+     * @param info WMS_ENDPOINT ImageryInfo
+     * @param tileProjection server projection that should be used by this tile source
+     */
+    public WMSEndpointTileSource(ImageryInfo info, Projection tileProjection) {
+        super(info, tileProjection);
+        CheckParameterUtil.ensure(info, "imageryType", x -> ImageryType.WMS_ENDPOINT.equals(x.getImageryType()));
+        try {
+            wmsi = new WMSImagery(info.getUrl());
+        } catch (IOException | WMSGetCapabilitiesException e) {
+            throw new IllegalArgumentException(e);
+        }
+        layers = info.getDefaultLayers();
+        initProjection();
+        urlPattern = wmsi.buildGetMapUrl(layers, info.isTransparent());
+        this.headers.putAll(info.getCustomHttpHeaders());
+    }
+
+    @Override
+    public int getDefaultTileSize() {
+        return WMSLayer.PROP_IMAGE_SIZE.get();
+    }
+
+    @Override
+    public String getTileUrl(int zoom, int tilex, int tiley) {
+        String bbox = getBbox(zoom, tilex, tiley, wmsi.belowWMS130() ? false : getTileProjection().switchXY());
+
+        // Using StringBuffer and generic PATTERN_PARAM matcher gives 2x performance improvement over replaceAll
+        StringBuffer url = new StringBuffer(urlPattern.length());
+        Matcher matcher = PATTERN_PARAM.matcher(urlPattern);
+        while (matcher.find()) {
+            String replacement;
+            switch (matcher.group(1)) {
+            case "proj":
+                replacement = getServerCRS();
+                break;
+            case "bbox":
+                replacement = bbox;
+                break;
+            case "width":
+            case "height":
+                replacement = String.valueOf(getTileSize());
+                break;
+            default:
+                replacement = '{' + matcher.group(1) + '}';
+            }
+            matcher.appendReplacement(url, replacement);
+        }
+        matcher.appendTail(url);
+        return url.toString();
+    }
+
+    /**
+     *
+     * @return list of EPSG codes that current layer selection supports (this may differ from layer to layer)
+     */
+    public List<String> getServerProjections() {
+        return wmsi.getLayers(layers).stream().flatMap(x -> x.getCrs().stream()).distinct().collect(Collectors.toList());
+    }
+
+    @Override
+    public Map<String, String> getHeaders() {
+        return headers;
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/data/imagery/WMTSCapabilities.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/imagery/WMTSCapabilities.java	(revision 13733)
+++ /trunk/src/org/openstreetmap/josm/data/imagery/WMTSCapabilities.java	(revision 13733)
@@ -0,0 +1,63 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.imagery;
+
+import java.util.Collection;
+
+import org.openstreetmap.josm.data.imagery.GetCapabilitiesParseHelper.TransferMode;
+import org.openstreetmap.josm.data.imagery.WMTSTileSource.Layer;
+
+/**
+ * Data object containing WMTS GetCapabilities document
+ *
+ * @author Wiktor Niesiobedzki
+ *
+ */
+public class WMTSCapabilities {
+    private String baseUrl;
+    private TransferMode transferMode;
+    private Collection<Layer> layers;
+
+
+    /**
+     *
+     * @param baseUrl of this service
+     * @param transferMode either KVP (key-value pairs in URL parameters) or RESTful (part of path)
+     */
+    public WMTSCapabilities(String baseUrl, TransferMode transferMode) {
+        this.baseUrl = baseUrl;
+        this.transferMode = transferMode;
+    }
+
+    /**
+     *
+     * @param layers layers to add to this document
+     */
+    public void addLayers(Collection<Layer> layers) {
+        this.layers = layers;
+
+    }
+
+    /**
+     *
+     * @return layers defined by this service
+     */
+    public Collection<Layer> getLayers() {
+        return layers;
+    }
+
+    /**
+     *
+     * @return base url for this service
+     */
+    public String getBaseUrl() {
+        return baseUrl;
+    }
+
+    /**
+     *
+     * @return transfer mode (KVP or RESTful) for this service
+     */
+    public TransferMode getTransferMode() {
+        return transferMode;
+    }
+}
Index: unk/src/org/openstreetmap/josm/data/imagery/WMTSDefaultLayer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/imagery/WMTSDefaultLayer.java	(revision 13732)
+++ 	(revision )
@@ -1,28 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.data.imagery;
-
-/**
- * WMTS default layer.
- * @since 11257
- */
-public class WMTSDefaultLayer extends DefaultLayer {
-    private final String tileMatrixSet;
-
-    /**
-     * Constructs a new {@code WMTSDefaultLayer}.
-     * @param layerName layer name
-     * @param tileMatrixSet tile matrix set
-     */
-    public WMTSDefaultLayer(String layerName, String tileMatrixSet) {
-        super(layerName);
-        this.tileMatrixSet = tileMatrixSet;
-    }
-
-    /**
-     * Returns the tile matrix set.
-     * @return the tile matrix set
-     */
-    public String getTileMatrixSet() {
-        return tileMatrixSet;
-    }
-}
Index: /trunk/src/org/openstreetmap/josm/data/imagery/WMTSTileSource.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/imagery/WMTSTileSource.java	(revision 13732)
+++ /trunk/src/org/openstreetmap/josm/data/imagery/WMTSTileSource.java	(revision 13733)
@@ -51,4 +51,6 @@
 import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.imagery.GetCapabilitiesParseHelper.TransferMode;
+import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryType;
 import org.openstreetmap.josm.data.projection.Projection;
 import org.openstreetmap.josm.data.projection.Projections;
@@ -126,5 +128,11 @@
     }
 
-    private static class TileMatrixSet {
+    /**
+     *
+     * class representing WMTS TileMatrixSet
+     * This connects projection and TileMatrix (how the map is divided in tiles)
+     *
+     */
+    public static class TileMatrixSet {
 
         private final List<TileMatrix> tileMatrix;
@@ -154,4 +162,12 @@
             return "TileMatrixSet [crs=" + crs + ", identifier=" + identifier + ']';
         }
+
+        /**
+         *
+         * @return identifier of this TileMatrixSet
+         */
+        public String getIdentifier() {
+            return identifier;
+        }
     }
 
@@ -162,5 +178,9 @@
     }
 
-    private static class Layer {
+    /**
+     * Class representing WMTS Layer information
+     *
+     */
+    public static class Layer {
         private String format;
         private String identifier;
@@ -202,4 +222,42 @@
                     + tileMatrixSet + ", baseUrl=" + baseUrl + ", style=" + style + ']';
         }
+
+        /**
+         *
+         * @return identifier of this layer
+         */
+        public String getIdentifier() {
+            return identifier;
+        }
+
+        /**
+         *
+         * @return style of this layer
+         */
+        public String getStyle() {
+            return style;
+        }
+
+        /**
+         *
+         * @return
+         */
+        public TileMatrixSet getTileMatrixSet() {
+            return tileMatrixSet;
+        }
+    }
+
+    /**
+     * Exception thrown when praser doesn't find expected information in GetCapabilities document
+     *
+     */
+    public static class WMTSGetCapabilitiesException extends Exception {
+
+        /**
+         * @param cause description of cause
+         */
+        public WMTSGetCapabilitiesException(String cause) {
+            super(cause);
+        }
     }
 
@@ -211,55 +269,5 @@
             super(Main.parent, tr("Select WMTS layer"), tr("Add layers"), tr("Cancel"));
             this.layers = groupLayersByNameAndTileMatrixSet(layers);
-            //getLayersTable(layers, Main.getProjection())
-            this.list = new JTable(
-                    new AbstractTableModel() {
-                        @Override
-                        public Object getValueAt(int rowIndex, int columnIndex) {
-                            switch (columnIndex) {
-                            case 0:
-                                return SelectLayerDialog.this.layers.get(rowIndex).getValue()
-                                        .stream()
-                                        .map(Layer::getUserTitle)
-                                        .collect(Collectors.joining(", ")); //this should be only one
-                            case 1:
-                                return SelectLayerDialog.this.layers.get(rowIndex).getValue()
-                                        .stream()
-                                        .map(x -> x.tileMatrixSet.crs)
-                                        .collect(Collectors.joining(", "));
-                            case 2:
-                                return SelectLayerDialog.this.layers.get(rowIndex).getValue()
-                                        .stream()
-                                        .map(x -> x.tileMatrixSet.identifier)
-                                        .collect(Collectors.joining(", ")); //this should be only one
-                            default:
-                                throw new IllegalArgumentException();
-                            }
-                        }
-
-                        @Override
-                        public int getRowCount() {
-                            return SelectLayerDialog.this.layers.size();
-                        }
-
-                        @Override
-                        public int getColumnCount() {
-                            return 3;
-                        }
-
-                        @Override
-                        public String getColumnName(int column) {
-                            switch (column) {
-                            case 0: return tr("Layer name");
-                            case 1: return tr("Projection");
-                            case 2: return tr("Matrix set identifier");
-                            default:
-                                throw new IllegalArgumentException();
-                            }
-                        }
-                    });
-            this.list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-            this.list.setAutoCreateRowSorter(true);
-            this.list.setRowSelectionAllowed(true);
-            this.list.setColumnSelectionAllowed(false);
+            this.list = getLayerSelectionPanel(this.layers);
             JPanel panel = new JPanel(new GridBagLayout());
             panel.add(new JScrollPane(this.list), GBC.eol().fill());
@@ -273,12 +281,7 @@
             }
             Layer selectedLayer = layers.get(list.convertRowIndexToModel(index)).getValue().get(0);
-            return new WMTSDefaultLayer(selectedLayer.identifier, selectedLayer.tileMatrixSet.identifier);
-        }
-
-        private static List<Entry<String, List<Layer>>> groupLayersByNameAndTileMatrixSet(Collection<Layer> layers) {
-            Map<String, List<Layer>> layerByName = layers.stream().collect(
-                    Collectors.groupingBy(x -> x.identifier + '\u001c' + x.tileMatrixSet.identifier));
-            return layerByName.entrySet().stream().sorted(Map.Entry.comparingByKey()).collect(Collectors.toList());
-        }
+            return new DefaultLayer(ImageryType.WMTS, selectedLayer.identifier, selectedLayer.style, selectedLayer.tileMatrixSet.identifier);
+        }
+
     }
 
@@ -292,5 +295,5 @@
     private ScaleList nativeScaleList;
 
-    private final WMTSDefaultLayer defaultLayer;
+    private final DefaultLayer defaultLayer;
 
     private Projection tileProjection;
@@ -300,27 +303,26 @@
      * @param info imagery info
      * @throws IOException if any I/O error occurs
+     * @throws WMTSGetCapabilitiesException
      * @throws IllegalArgumentException if any other error happens for the given imagery info
      */
-    public WMTSTileSource(ImageryInfo info) throws IOException {
+    public WMTSTileSource(ImageryInfo info) throws IOException, WMTSGetCapabilitiesException {
         super(info);
         CheckParameterUtil.ensureThat(info.getDefaultLayers().size() < 2, "At most 1 default layer for WMTS is supported");
-
+        this.headers.putAll(info.getCustomHttpHeaders());
         this.baseUrl = GetCapabilitiesParseHelper.normalizeCapabilitiesUrl(handleTemplate(info.getUrl()));
-        this.layers = getCapabilities();
+        WMTSCapabilities capabilities = getCapabilities(baseUrl, headers);
+        this.layers =  capabilities.getLayers();
+        this.baseUrl = capabilities.getBaseUrl();
+        this.transferMode = capabilities.getTransferMode();
         if (info.getDefaultLayers().isEmpty()) {
             Logging.warn(tr("No default layer selected, choosing first layer."));
             if (!layers.isEmpty()) {
                 Layer first = layers.iterator().next();
-                this.defaultLayer = new WMTSDefaultLayer(first.identifier, first.tileMatrixSet.identifier);
+                this.defaultLayer = new DefaultLayer(info.getImageryType(), first.identifier, first.style, first.tileMatrixSet.identifier);
             } else {
                 this.defaultLayer = null;
             }
         } else {
-            DefaultLayer defLayer = info.getDefaultLayers().iterator().next();
-            if (defLayer instanceof WMTSDefaultLayer) {
-                this.defaultLayer = (WMTSDefaultLayer) defLayer;
-            } else {
-                this.defaultLayer = null;
-            }
+            this.defaultLayer = info.getDefaultLayers().iterator().next();
         }
         if (this.layers.isEmpty())
@@ -343,5 +345,5 @@
                 // only one tile matrix set with matching projection - no point in asking
                 Layer selectedLayer = ls.get(0);
-                return new WMTSDefaultLayer(selectedLayer.identifier, selectedLayer.tileMatrixSet.identifier);
+                return new DefaultLayer(ImageryType.WMTS, selectedLayer.identifier, selectedLayer.style, selectedLayer.tileMatrixSet.identifier);
             }
         }
@@ -366,11 +368,15 @@
     }
 
-    /**
+
+    /**
+     * @param url of the getCapabilities document
+     * @param headers HTTP headers to set when calling getCapabilities url
      * @return capabilities
      * @throws IOException in case of any I/O error
+     * @throws WMTSGetCapabilitiesException
      * @throws IllegalArgumentException in case of any other error
      */
-    private Collection<Layer> getCapabilities() throws IOException {
-        try (CachedFile cf = new CachedFile(baseUrl); InputStream in = cf.setHttpHeaders(headers).
+    public static WMTSCapabilities getCapabilities(String url, Map<String, String> headers) throws IOException, WMTSGetCapabilitiesException {
+        try (CachedFile cf = new CachedFile(url); InputStream in = cf.setHttpHeaders(headers).
                 setMaxAge(Config.getPref().getLong("wmts.capabilities.cache.max_age", 7 * CachedFile.DAYS)).
                 setCachingStrategy(CachedFile.CachingStrategy.IfModifiedSince).
@@ -379,21 +385,37 @@
             if (data.length == 0) {
                 cf.clear();
-                throw new IllegalArgumentException("Could not read data from: " + baseUrl);
+                throw new IllegalArgumentException("Could not read data from: " + url);
             }
 
             try {
                 XMLStreamReader reader = GetCapabilitiesParseHelper.getReader(new ByteArrayInputStream(data));
-                Collection<Layer> ret = new ArrayList<>();
+                WMTSCapabilities ret = null;
+                Collection<Layer> layers = null;
                 for (int event = reader.getEventType(); reader.hasNext(); event = reader.next()) {
                     if (event == XMLStreamReader.START_ELEMENT) {
                         if (GetCapabilitiesParseHelper.QN_OWS_OPERATIONS_METADATA.equals(reader.getName())) {
-                            parseOperationMetadata(reader);
+                            ret = parseOperationMetadata(reader);
                         }
 
                         if (QN_CONTENTS.equals(reader.getName())) {
-                            ret = parseContents(reader);
+                            layers = parseContents(reader);
                         }
                     }
                 }
+                if (ret == null) {
+                    /*
+                     *  see #12168 - create dummy operation metadata - not all WMTS services provide this information
+                     *
+                     *  WMTS Standard:
+                     *  > Resource oriented architecture style HTTP encodings SHALL not be described in the OperationsMetadata section.
+                     *
+                     *  And OperationMetada is not mandatory element. So REST mode is justifiable
+                     */
+                    ret = new WMTSCapabilities(url, TransferMode.REST);
+                }
+                if (layers == null) {
+                    throw new WMTSGetCapabilitiesException(tr("WMTS Capabilties document did not contain layers in url:  {0}", url));
+                }
+                ret.addLayers(layers);
                 return ret;
             } catch (XMLStreamException e) {
@@ -456,4 +478,7 @@
         supportedMimeTypes.add("image/jpgpng");         // used by ESRI
         supportedMimeTypes.add("image/png8");           // used by geoserver
+        if (supportedMimeTypes.contains("image/jpeg")) {
+            supportedMimeTypes.add("image/jpg"); // sometimes mispelled by Arcgis
+        }
         Collection<String> unsupportedFormats = new ArrayList<>();
 
@@ -639,10 +664,11 @@
     /**
      * Parses OperationMetadata section. Returns when reader is on OperationsMetadata closing tag.
-     * Sets this.baseUrl and this.transferMode
+     * return WMTSCapabilities with baseUrl and transferMode
      *
      * @param reader StAX reader instance
+     * @return WMTSCapabilities with baseUrl and transferMode set
      * @throws XMLStreamException See {@link XMLStreamReader}
      */
-    private void parseOperationMetadata(XMLStreamReader reader) throws XMLStreamException {
+    private static WMTSCapabilities parseOperationMetadata(XMLStreamReader reader) throws XMLStreamException {
         for (int event = reader.getEventType();
                 reader.hasNext() && !(event == XMLStreamReader.END_ELEMENT &&
@@ -657,8 +683,11 @@
                             GetCapabilitiesParseHelper.QN_OWS_GET
                     )) {
-                this.baseUrl = reader.getAttributeValue(GetCapabilitiesParseHelper.XLINK_NS_URL, "href");
-                this.transferMode = GetCapabilitiesParseHelper.getTransferMode(reader);
-            }
-        }
+                return new WMTSCapabilities(
+                        reader.getAttributeValue(GetCapabilitiesParseHelper.XLINK_NS_URL, "href"),
+                        GetCapabilitiesParseHelper.getTransferMode(reader)
+                        );
+            }
+        }
+        return null;
     }
 
@@ -671,5 +700,5 @@
             return;
         List<Layer> matchingLayers = layers.stream().filter(
-                l -> l.identifier.equals(defaultLayer.layerName) && l.tileMatrixSet.crs.equals(proj.toCode()))
+                l -> l.identifier.equals(defaultLayer.getLayerName()) && l.tileMatrixSet.crs.equals(proj.toCode()))
                 .collect(Collectors.toList());
         if (matchingLayers.size() > 1) {
@@ -686,5 +715,5 @@
                 this.tileProjection = null;
                 for (Layer layer : layers) {
-                    if (!layer.identifier.equals(defaultLayer.layerName)) {
+                    if (!layer.identifier.equals(defaultLayer.getLayerName())) {
                         continue;
                     }
@@ -922,4 +951,65 @@
     }
 
+    public static JTable getLayerSelectionPanel(List<Entry<String, List<Layer>>> layers) {
+        JTable list = new JTable(
+                new AbstractTableModel() {
+                    @Override
+                    public Object getValueAt(int rowIndex, int columnIndex) {
+                        switch (columnIndex) {
+                        case 0:
+                            return layers.get(rowIndex).getValue()
+                                    .stream()
+                                    .map(Layer::getUserTitle)
+                                    .collect(Collectors.joining(", ")); //this should be only one
+                        case 1:
+                            return layers.get(rowIndex).getValue()
+                                    .stream()
+                                    .map(x -> x.tileMatrixSet.crs)
+                                    .collect(Collectors.joining(", "));
+                        case 2:
+                            return layers.get(rowIndex).getValue()
+                                    .stream()
+                                    .map(x -> x.tileMatrixSet.identifier)
+                                    .collect(Collectors.joining(", ")); //this should be only one
+                        default:
+                            throw new IllegalArgumentException();
+                        }
+                    }
+
+                    @Override
+                    public int getRowCount() {
+                        return layers.size();
+                    }
+
+                    @Override
+                    public int getColumnCount() {
+                        return 3;
+                    }
+
+                    @Override
+                    public String getColumnName(int column) {
+                        switch (column) {
+                        case 0: return tr("Layer name");
+                        case 1: return tr("Projection");
+                        case 2: return tr("Matrix set identifier");
+                        default:
+                            throw new IllegalArgumentException();
+                        }
+                    }
+                });
+        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+        list.setAutoCreateRowSorter(true);
+        list.setRowSelectionAllowed(true);
+        list.setColumnSelectionAllowed(false);
+        return list;
+    }
+
+    public static List<Entry<String, List<Layer>>> groupLayersByNameAndTileMatrixSet(Collection<Layer> layers) {
+        Map<String, List<Layer>> layerByName = layers.stream().collect(
+                Collectors.groupingBy(x -> x.identifier + '\u001c' + x.tileMatrixSet.identifier));
+        return layerByName.entrySet().stream().sorted(Map.Entry.comparingByKey()).collect(Collectors.toList());
+    }
+
+
     /**
      * @return set of projection codes that this TileSource supports
Index: /trunk/src/org/openstreetmap/josm/gui/bbox/SlippyMapBBoxChooser.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/bbox/SlippyMapBBoxChooser.java	(revision 13732)
+++ /trunk/src/org/openstreetmap/josm/gui/bbox/SlippyMapBBoxChooser.java	(revision 13733)
@@ -21,4 +21,5 @@
 import java.util.Set;
 import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.TimeUnit;
 
 import javax.swing.ButtonModel;
@@ -158,5 +159,5 @@
         TileLoaderFactory cachedLoaderFactory = AbstractCachedTileSourceLayer.getTileLoaderFactory("TMS", TMSCachedTileLoader.class);
         if (cachedLoaderFactory != null) {
-            cachedLoader = cachedLoaderFactory.makeTileLoader(this, headers);
+            cachedLoader = cachedLoaderFactory.makeTileLoader(this, headers, TimeUnit.HOURS.toSeconds(1));
         } else {
             cachedLoader = null;
Index: /trunk/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java	(revision 13732)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java	(revision 13733)
@@ -203,4 +203,5 @@
     // prepared to be moved to the painter
     protected TileCoordinateConverter coordinateConverter;
+    private final long minimumTileExpire;
 
     /**
@@ -214,4 +215,5 @@
         getFilterSettings().addFilterChangeListener(this);
         getDisplaySettings().addSettingsChangeListener(this);
+        this.minimumTileExpire = info.getMinimumTileExpire();
     }
 
@@ -274,5 +276,5 @@
         Map<String, String> headers = getHeaders(tileSource);
 
-        tileLoader = getTileLoaderFactory().makeTileLoader(this, headers);
+        tileLoader = getTileLoaderFactory().makeTileLoader(this, headers, minimumTileExpire);
 
         try {
@@ -1759,5 +1761,5 @@
         public PrecacheTask(ProgressMonitor progressMonitor) {
             this.progressMonitor = progressMonitor;
-            this.tileLoader = getTileLoaderFactory().makeTileLoader(this, getHeaders(tileSource));
+            this.tileLoader = getTileLoaderFactory().makeTileLoader(this, getHeaders(tileSource), minimumTileExpire);
             if (this.tileLoader instanceof TMSCachedTileLoader) {
                 ((TMSCachedTileLoader) this.tileLoader).setDownloadExecutor(
Index: /trunk/src/org/openstreetmap/josm/gui/layer/ImageryLayer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/ImageryLayer.java	(revision 13732)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/ImageryLayer.java	(revision 13733)
@@ -196,4 +196,5 @@
         switch(info.getImageryType()) {
         case WMS:
+        case WMS_ENDPOINT:
             return new WMSLayer(info);
         case WMTS:
Index: /trunk/src/org/openstreetmap/josm/gui/layer/WMSLayer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/WMSLayer.java	(revision 13732)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/WMSLayer.java	(revision 13733)
@@ -25,4 +25,5 @@
 import org.openstreetmap.josm.data.imagery.TemplatedWMSTileSource;
 import org.openstreetmap.josm.data.imagery.WMSCachedTileLoader;
+import org.openstreetmap.josm.data.imagery.WMSEndpointTileSource;
 import org.openstreetmap.josm.data.preferences.BooleanProperty;
 import org.openstreetmap.josm.data.preferences.IntegerProperty;
@@ -57,5 +58,5 @@
     private static final String CACHE_REGION_NAME = "WMS";
 
-    private final List<String> serverProjections;
+    private List<String> serverProjections;
 
     /**
@@ -65,7 +66,10 @@
     public WMSLayer(ImageryInfo info) {
         super(info);
-        CheckParameterUtil.ensureThat(info.getImageryType() == ImageryType.WMS, "ImageryType is WMS");
+        CheckParameterUtil.ensureThat(info.getImageryType() == ImageryType.WMS || info.getImageryType() == ImageryType.WMS_ENDPOINT, "ImageryType is WMS");
         CheckParameterUtil.ensureParameterNotNull(info.getUrl(), "info.url");
-        TemplatedWMSTileSource.checkUrl(info.getUrl());
+        if (info.getImageryType() == ImageryType.WMS) {
+            TemplatedWMSTileSource.checkUrl(info.getUrl());
+
+        }
         this.serverProjections = new ArrayList<>(info.getServerProjections());
     }
@@ -89,6 +93,22 @@
     @Override
     protected AbstractWMSTileSource getTileSource() {
-        AbstractWMSTileSource tileSource = new TemplatedWMSTileSource(
-                info, chooseProjection(Main.getProjection()));
+        AbstractWMSTileSource tileSource;
+        if (info.getImageryType() == ImageryType.WMS) {
+            tileSource = new TemplatedWMSTileSource(info, chooseProjection(Main.getProjection()));
+        } else {
+            /*
+             *  Chicken-and-egg problem. We want to create tile source, but supported projections we can get only
+             *  from this tile source. So create tilesource first with dummy Main.getProjection(), and then update
+             *  once we update server projections.
+             *
+             *  Thus:
+             *  * it is not required to provide projections for wms_endpoint imagery types
+             *  * we always use current definitions returned by server
+             */
+            WMSEndpointTileSource endpointTileSource = new WMSEndpointTileSource(info, Main.getProjection());
+            this.serverProjections = endpointTileSource.getServerProjections();
+            endpointTileSource.setTileProjection(chooseProjection(Main.getProjection()));
+            tileSource = endpointTileSource;
+        }
         info.setAttribution(tileSource);
         return tileSource;
Index: /trunk/src/org/openstreetmap/josm/gui/layer/WMTSLayer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/WMTSLayer.java	(revision 13732)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/WMTSLayer.java	(revision 13733)
@@ -13,4 +13,5 @@
 import org.openstreetmap.josm.data.imagery.WMSCachedTileLoader;
 import org.openstreetmap.josm.data.imagery.WMTSTileSource;
+import org.openstreetmap.josm.data.imagery.WMTSTileSource.WMTSGetCapabilitiesException;
 import org.openstreetmap.josm.data.projection.Projection;
 import org.openstreetmap.josm.gui.MainApplication;
@@ -64,5 +65,5 @@
             }
             return null;
-        } catch (IOException e) {
+        } catch (IOException | WMTSGetCapabilitiesException e) {
             Logging.warn(e);
             throw new IllegalArgumentException(e);
Index: /trunk/src/org/openstreetmap/josm/gui/preferences/imagery/HeadersTable.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/preferences/imagery/HeadersTable.java	(revision 13733)
+++ /trunk/src/org/openstreetmap/josm/gui/preferences/imagery/HeadersTable.java	(revision 13733)
@@ -0,0 +1,120 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.preferences.imagery;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.GridBagLayout;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import javax.swing.table.AbstractTableModel;
+
+import org.openstreetmap.josm.tools.GBC;
+
+/**
+ * Simple table for editing HTTP headers
+ * @author Wiktor Niesiobedzki
+ *
+ */
+public class HeadersTable extends JPanel {
+
+    private final class HeaderTableModel extends AbstractTableModel {
+        @Override
+        public String getColumnName(int column) {
+            switch (column) {
+            case 0:
+                return tr("Header name");
+            case 1:
+                return tr("Header value");
+            default:
+                return "";
+            }
+        }
+
+        @Override
+        public int getRowCount() {
+            return headers.size() + 1;
+        }
+
+        @Override
+        public int getColumnCount() {
+            return 2;
+        }
+
+        @Override
+        public Object getValueAt(int row, int col) {
+            if (row < headers.size()) {
+                return headers.get(row)[col];
+            }
+            return "";
+        }
+
+        @Override
+        public boolean isCellEditable(int row, int column) {
+            return true;
+        }
+
+        @Override
+        public void setValueAt(Object value, int row, int col) {
+            if (row < headers.size()) {
+                String[] headerRow = headers.get(row);
+                headerRow[col] = (String) value;
+                if ("".equals(headerRow[0]) && "".equals(headerRow[1])) {
+                    headers.remove(row);
+                    fireTableRowsDeleted(row, row);
+                }
+
+            } else if (row == headers.size()) {
+                String[] entry = new String[] { "", "" };
+                entry[col] = (String) value;
+                headers.add(entry);
+                fireTableRowsInserted(row + 1, row + 1);
+            }
+            fireTableCellUpdated(row, col);
+        }
+    }
+
+    private final JTable table;
+    private List<String[]> headers;
+
+    /**
+     * Creates empty table
+     */
+    public HeadersTable() {
+        this(new ConcurrentHashMap<>());
+    }
+
+    /**
+     * Create table prefilled with headers
+     * @param headers
+     */
+    public HeadersTable(Map<String, String> headers) {
+        super(new GridBagLayout());
+        this.headers = getHeadersAsVector(headers);
+        table = new JTable(new HeaderTableModel());
+        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+        table.setAutoCreateRowSorter(true);
+        table.setRowSelectionAllowed(false);
+        table.setColumnSelectionAllowed(false);
+        add(new JScrollPane(table), GBC.eol().fill());
+    }
+
+    private static List<String[]> getHeadersAsVector(Map<String, String> headers) {
+        return headers.entrySet().stream().sorted((e1, e2) -> e1.getKey().compareTo(e2.getKey()))
+                .map(e -> new String[] { e.getKey(), e.getValue() }).collect(Collectors.toList());
+    }
+
+    /**
+     * @return headers provided by user
+     */
+    public Map<String, String> getHeaders() {
+        return headers.stream().distinct().collect(Collectors.toMap(x -> x[0], x -> x[1]));
+    }
+
+}
Index: /trunk/src/org/openstreetmap/josm/io/imagery/ImageryReader.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/imagery/ImageryReader.java	(revision 13732)
+++ /trunk/src/org/openstreetmap/josm/io/imagery/ImageryReader.java	(revision 13733)
@@ -7,12 +7,13 @@
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Stack;
+import java.util.concurrent.ConcurrentHashMap;
 
 import javax.xml.parsers.ParserConfigurationException;
 
+import org.openstreetmap.josm.data.imagery.DefaultLayer;
 import org.openstreetmap.josm.data.imagery.ImageryInfo;
 import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryBounds;
@@ -57,5 +58,8 @@
         NO_TILESUM,
         METADATA,
-        UNKNOWN,            // element is not recognized in the current context
+        DEFAULT_LAYERS,
+        CUSTOM_HTTP_HEADERS,
+        NOOP,
+        UNKNOWN,             // element is not recognized in the current context
     }
 
@@ -132,4 +136,6 @@
         private MultiMap<String, String> noTileChecksums;
         private Map<String, String> metadataHeaders;
+        private List<DefaultLayer> defaultLayers;
+        private Map<String, String> customHttpHeaders;
 
         @Override
@@ -145,4 +151,5 @@
             noTileHeaders = null;
             noTileChecksums = null;
+            customHttpHeaders = null;
         }
 
@@ -164,5 +171,7 @@
                     noTileHeaders = new MultiMap<>();
                     noTileChecksums = new MultiMap<>();
-                    metadataHeaders = new HashMap<>();
+                    metadataHeaders = new ConcurrentHashMap<>();
+                    defaultLayers = new ArrayList<>();
+                    customHttpHeaders = new ConcurrentHashMap<>();
                     String best = atts.getValue("eli-best");
                     if (TRUE.equals(best)) {
@@ -215,5 +224,7 @@
                         TILE_SIZE,
                         "valid-georeference",
-                        "mod-tile-features"
+                        "mod-tile-features",
+                        "transparent",
+                        "minimum-tile-expire"
                 ).contains(qName)) {
                     newState = State.ENTRY_ATTRIBUTE;
@@ -247,4 +258,9 @@
                     metadataHeaders.put(atts.getValue("header-name"), atts.getValue("metadata-key"));
                     newState = State.METADATA;
+                } else if ("defaultLayers".equals(qName)) {
+                    newState = State.DEFAULT_LAYERS;
+                } else if ("custom-http-header".equals(qName)) {
+                   customHttpHeaders.put(atts.getValue("header-name"), atts.getValue("header-value"));
+                   newState = State.CUSTOM_HTTP_HEADERS;
                 }
                 break;
@@ -269,4 +285,10 @@
                 if ("code".equals(qName)) {
                     newState = State.CODE;
+                }
+                break;
+            case DEFAULT_LAYERS:
+                if ("layer".equals(qName)) {
+                    newState = State.NOOP;
+                    defaultLayers.add(new DefaultLayer(entry.getImageryType(), atts.getValue("name"),atts.getValue("style"), atts.getValue("tileMatrixSet")));
                 }
                 break;
@@ -306,4 +328,8 @@
                     entry.setMetadataHeaders(metadataHeaders);
                     metadataHeaders = null;
+                    entry.setDefaultLayers(defaultLayers);
+                    defaultLayers = null;
+                    entry.setCustomHttpHeaders(customHttpHeaders);
+                    customHttpHeaders = null;
 
                     if (!skipEntry) {
@@ -323,4 +349,5 @@
                     switch(qName) {
                     case "type":
+                        ImageryType.values();
                         boolean found = false;
                         for (ImageryType type : ImageryType.values()) {
@@ -487,4 +514,10 @@
                 case "mod-tile-features":
                     entry.setModTileFeatures(Boolean.parseBoolean(accumulator.toString()));
+                    break;
+                case "transparent":
+                    entry.setTransparent(Boolean.parseBoolean(accumulator.toString()));
+                    break;
+                case "minimum-tile-expire":
+                    entry.setMinimumTileExpire(Integer.valueOf(accumulator.toString()));
                     break;
                 default: // Do nothing
Index: /trunk/src/org/openstreetmap/josm/io/imagery/WMSImagery.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/imagery/WMSImagery.java	(revision 13732)
+++ /trunk/src/org/openstreetmap/josm/io/imagery/WMSImagery.java	(revision 13733)
@@ -2,9 +2,10 @@
 package org.openstreetmap.josm.io.imagery;
 
-import java.awt.HeadlessException;
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.StringReader;
-import java.io.StringWriter;
 import java.net.MalformedURLException;
 import java.net.URL;
@@ -13,38 +14,28 @@
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
-import java.util.Locale;
-import java.util.NoSuchElementException;
+import java.util.Map;
 import java.util.Set;
-import java.util.regex.Matcher;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
 
 import javax.imageio.ImageIO;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.TransformerFactoryConfigurationError;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
 
 import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.imagery.DefaultLayer;
 import org.openstreetmap.josm.data.imagery.GetCapabilitiesParseHelper;
 import org.openstreetmap.josm.data.imagery.ImageryInfo;
+import org.openstreetmap.josm.data.imagery.LayerDetails;
+import org.openstreetmap.josm.data.projection.Projection;
 import org.openstreetmap.josm.data.projection.Projections;
-import org.openstreetmap.josm.tools.HttpClient;
-import org.openstreetmap.josm.tools.HttpClient.Response;
+import org.openstreetmap.josm.io.CachedFile;
 import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
 
 /**
@@ -53,34 +44,43 @@
 public class WMSImagery {
 
-    private static final class ChildIterator implements Iterator<Element> {
-        private Element child;
-
-        ChildIterator(Element parent) {
-            child = advanceToElement(parent.getFirstChild());
-        }
-
-        private static Element advanceToElement(Node firstChild) {
-            Node node = firstChild;
-            while (node != null && !(node instanceof Element)) {
-                node = node.getNextSibling();
-            }
-            return (Element) node;
-        }
-
-        @Override
-        public boolean hasNext() {
-            return child != null;
-        }
-
-        @Override
-        public Element next() {
-            if (!hasNext()) {
-                throw new NoSuchElementException("No next sibling.");
-            }
-            Element next = child;
-            child = advanceToElement(child.getNextSibling());
-            return next;
-        }
-    }
+
+    private static final String CAPABILITIES_QUERY_STRING = "SERVICE=WMS&REQUEST=GetCapabilities";
+
+    /**
+     * WMS namespace address
+     */
+    public static final String WMS_NS_URL = "http://www.opengis.net/wms";
+
+    // CHECKSTYLE.OFF: SingleSpaceSeparator
+    // WMS 1.0 - 1.3.0
+    private static final QName CAPABILITITES_ROOT_130 = new QName("WMS_Capabilities", WMS_NS_URL);
+    private static final QName QN_ABSTRACT            = new QName(WMS_NS_URL, "Abstract");
+    private static final QName QN_CAPABILITY          = new QName(WMS_NS_URL, "Capability");
+    private static final QName QN_CRS                 = new QName(WMS_NS_URL, "CRS");
+    private static final QName QN_DCPTYPE             = new QName(WMS_NS_URL, "DCPType");
+    private static final QName QN_FORMAT              = new QName(WMS_NS_URL, "Format");
+    private static final QName QN_GET                 = new QName(WMS_NS_URL, "Get");
+    private static final QName QN_GETMAP              = new QName(WMS_NS_URL, "GetMap");
+    private static final QName QN_HTTP                = new QName(WMS_NS_URL, "HTTP");
+    private static final QName QN_LAYER               = new QName(WMS_NS_URL, "Layer");
+    private static final QName QN_NAME                = new QName(WMS_NS_URL, "Name");
+    private static final QName QN_REQUEST             = new QName(WMS_NS_URL, "Request");
+    private static final QName QN_SERVICE             = new QName(WMS_NS_URL, "Service");
+    private static final QName QN_STYLE               = new QName(WMS_NS_URL, "Style");
+    private static final QName QN_TITLE               = new QName(WMS_NS_URL, "Title");
+    private static final QName QN_BOUNDINGBOX         = new QName(WMS_NS_URL, "BoundingBox");
+    private static final QName QN_EX_GEOGRAPHIC_BBOX  = new QName(WMS_NS_URL, "EX_GeographicBoundingBox");
+    private static final QName QN_WESTBOUNDLONGITUDE  = new QName(WMS_NS_URL, "westBoundLongitude");
+    private static final QName QN_EASTBOUNDLONGITUDE  = new QName(WMS_NS_URL, "eastBoundLongitude");
+    private static final QName QN_SOUTHBOUNDLATITUDE  = new QName(WMS_NS_URL, "southBoundLatitude");
+    private static final QName QN_NORTHBOUNDLATITUDE  = new QName(WMS_NS_URL, "northBoundLatitude");
+    private static final QName QN_ONLINE_RESOURCE     = new QName(WMS_NS_URL, "OnlineResource");
+
+    // WMS 1.1 - 1.1.1
+    private static final QName CAPABILITIES_ROOT_111 = new QName("WMT_MS_Capabilities");
+    private static final QName QN_SRS                = new QName("SRS");
+    private static final QName QN_LATLONBOUNDINGBOX  = new QName("LatLonBoundingBox");
+
+    // CHECKSTYLE.ON: SingleSpaceSeparator
 
     /**
@@ -120,12 +120,94 @@
     }
 
-    private List<LayerDetails> layers;
-    private URL serviceUrl;
-    private List<String> formats;
-    private String version = "1.1.1";
-
-    /**
-     * Returns the list of layers.
-     * @return the list of layers
+    private Map<String, String> headers = new ConcurrentHashMap<>();
+    private String version = "1.1.1"; // default version
+    private String getMapUrl;
+    private URL capabilitiesUrl;
+    private List<String> formats = new ArrayList<>();
+    private List<LayerDetails> layers = new ArrayList<>();
+
+    private String title;
+
+    /**
+     * Make getCapabilities request towards given URL
+     * @param url service url
+     * @throws IOException
+     * @throws WMSGetCapabilitiesException
+     */
+    public WMSImagery(String url) throws IOException, WMSGetCapabilitiesException {
+        this(url, null);
+    }
+
+    /**
+     * Make getCapabilities request towards given URL using headers
+     * @param url service url
+     * @param headers HTTP headers to be sent with request
+     * @throws IOException
+     * @throws WMSGetCapabilitiesException
+     */
+    public WMSImagery(String url, Map<String, String> headers) throws IOException, WMSGetCapabilitiesException {
+        if (headers != null) {
+            this.headers.putAll(headers);
+        }
+
+        IOException savedExc = null;
+        String workingAddress = null;
+        url_search:
+        for (String z: new String[]{
+                normalizeUrl(url),
+                url,
+                url + CAPABILITIES_QUERY_STRING,
+        }) {
+            for (String ver: new String[]{"", "&VERSION=1.3.0", "&VERSION=1.1.1"}) {
+                try {
+                    attemptGetCapabilities(z + ver);
+                    workingAddress = z;
+                    calculateChildren();
+                    // clear saved exception - we've got something working
+                    savedExc = null;
+                    break url_search;
+                } catch (IOException e) {
+                    savedExc = e;
+                    Logging.warn(e);
+                }
+            }
+        }
+
+        if (workingAddress != null) {
+            try {
+                capabilitiesUrl = new URL(workingAddress);
+            } catch (MalformedURLException e) {
+                if (savedExc != null) {
+                    savedExc = e;
+                }
+                try {
+                    capabilitiesUrl = new File(workingAddress).toURI().toURL();
+                } catch (MalformedURLException e1) {
+                    // do nothing, raise original exception
+                }
+            }
+        }
+
+        if (savedExc != null) {
+            throw savedExc;
+        }
+    }
+
+    private void calculateChildren() {
+        Map<LayerDetails, List<LayerDetails>> layerChildren = layers.stream()
+                .filter(x -> x.getParent() != null) // exclude top-level elements
+                .collect(Collectors.groupingBy(LayerDetails::getParent));
+        for (LayerDetails ld: layers) {
+            if (layerChildren.containsKey(ld)) {
+                ld.setChildren(layerChildren.get(ld));
+            }
+        }
+        // leave only top-most elements in the list
+        layers = layers.stream().filter(x -> x.getParent() == null).collect(Collectors.toCollection(ArrayList::new));
+    }
+
+    /**
+     * Returns the list of top-level layers.
+     * @return the list of top-level layers
      */
     public List<LayerDetails> getLayers() {
@@ -134,37 +216,20 @@
 
     /**
-     * Returns the service URL.
-     * @return the service URL
-     */
-    public URL getServiceUrl() {
-        return serviceUrl;
-    }
-
-    /**
-     * Returns the WMS version used.
-     * @return the WMS version used (1.1.1 or 1.3.0)
-     * @since 13358
-     */
-    public String getVersion() {
-        return version;
-    }
-
-    /**
      * Returns the list of supported formats.
      * @return the list of supported formats
      */
-    public List<String> getFormats() {
+    public Collection<String> getFormats() {
         return Collections.unmodifiableList(formats);
     }
 
     /**
-     * Gets the preffered format for this imagery layer.
-     * @return The preffered format as mime type.
-     */
-    public String getPreferredFormats() {
-        if (formats.contains("image/jpeg")) {
+     * Gets the preferred format for this imagery layer.
+     * @return The preferred format as mime type.
+     */
+    public String getPreferredFormat() {
+        if (formats.contains("image/png")) {
+            return "image/png";
+        } else if (formats.contains("image/jpeg")) {
             return "image/jpeg";
-        } else if (formats.contains("image/png")) {
-            return "image/png";
         } else if (formats.isEmpty()) {
             return null;
@@ -174,8 +239,16 @@
     }
 
-    String buildRootUrl() {
-        if (serviceUrl == null) {
+    /**
+     * @return root URL of services in this GetCapabilities
+     */
+    public String buildRootUrl() {
+        if (getMapUrl == null && capabilitiesUrl == null) {
             return null;
         }
+        if (getMapUrl != null) {
+            return getMapUrl;
+        }
+
+        URL serviceUrl = capabilitiesUrl;
         StringBuilder a = new StringBuilder(serviceUrl.getProtocol());
         a.append("://").append(serviceUrl.getHost());
@@ -194,174 +267,350 @@
 
     /**
-     * Returns the URL for the "GetMap" WMS request in JPEG format.
-     * @param selectedLayers the list of selected layers, matching the "LAYERS" WMS request argument
-     * @return the URL for the "GetMap" WMS request
-     */
-    public String buildGetMapUrl(Collection<LayerDetails> selectedLayers) {
-        return buildGetMapUrl(selectedLayers, "image/jpeg");
-    }
-
-    /**
-     * Returns the URL for the "GetMap" WMS request.
-     * @param selectedLayers the list of selected layers, matching the "LAYERS" WMS request argument
-     * @param format the requested image format, matching the "FORMAT" WMS request argument
-     * @return the URL for the "GetMap" WMS request
-     */
-    public String buildGetMapUrl(Collection<LayerDetails> selectedLayers, String format) {
-        return buildRootUrl() + "FORMAT=" + format + (imageFormatHasTransparency(format) ? "&TRANSPARENT=TRUE" : "")
-                + "&VERSION=" + version + "&SERVICE=WMS&REQUEST=GetMap&LAYERS="
-                + selectedLayers.stream().map(x -> x.ident).collect(Collectors.joining(","))
-                + "&STYLES=&" + ("1.3.0".equals(version) ? "CRS" : "SRS") + "={proj}&WIDTH={width}&HEIGHT={height}&BBOX={bbox}";
-    }
-
-    /**
-     * Attempts WMS "GetCapabilities" request and initializes internal variables if successful.
-     * @param serviceUrlStr WMS service URL
-     * @throws IOException if any I/O errors occurs
-     * @throws WMSGetCapabilitiesException if the WMS server replies a ServiceException
-     */
-    public void attemptGetCapabilities(String serviceUrlStr) throws IOException, WMSGetCapabilitiesException {
+     * Returns URL for accessing GetMap service. String will contain following parameters:
+     * * {proj} - that needs to be replaced with projection (one of {@link #getServerProjections(List)})
+     * * {width} - that needs to be replaced with width of the tile
+     * * {height} - that needs to be replaces with height of the tile
+     * * {bbox} - that needs to be replaced with area that should be fetched (in {proj} coordinates)
+     *
+     * Format of the response will be calculated using {@link #getPreferredFormat()}
+     *
+     * @param selectedLayers list of DefaultLayer selection of layers to be shown
+     * @param transparent whether returned images should contain transparent pixels (if supported by format)
+     * @return URL template for GetMap service containing
+     */
+    public String buildGetMapUrl(List<DefaultLayer> selectedLayers, boolean transparent) {
+        return buildGetMapUrl(
+                getLayers(selectedLayers),
+                selectedLayers.stream().map(x -> x.getStyle()).collect(Collectors.toList()),
+                transparent);
+    }
+
+    /**
+     * @see #buildGetMapUrl(List, boolean)
+     *
+     * @param selectedLayers selected layers as subset of the tree returned by {@link #getLayers()}
+     * @param selectedStyles selected styles for all selectedLayers
+     * @param transparent whether returned images should contain transparent pixels (if supported by format)
+     * @return URL template for GetMap service
+     */
+    public String buildGetMapUrl(List<LayerDetails> selectedLayers, List<String> selectedStyles, boolean transparent) {
+        return buildGetMapUrl(
+                selectedLayers.stream().map(x -> x.getName()).collect(Collectors.toList()),
+                selectedStyles,
+                getPreferredFormat(),
+                transparent);
+    }
+
+    /**
+     * @see #buildGetMapUrl(List, boolean)
+     *
+     * @param selectedLayers selected layers as list of strings
+     * @param selectedStyles selected styles of layers as list of strings
+     * @param format format of the response - one of {@link #getFormats()}
+     * @param transparent whether returned images should contain transparent pixels (if supported by format)
+     * @return URL template for GetMap service
+     */
+    public String buildGetMapUrl(List<String> selectedLayers,
+            Collection<String> selectedStyles,
+            String format,
+            boolean transparent) {
+
+        Utils.ensure(selectedStyles == null || selectedLayers.size() == selectedStyles.size(),
+                tr("Styles size {0} doesn't match layers size {1}"),
+                selectedStyles == null ? 0 : selectedStyles.size(),
+                        selectedLayers.size());
+
+        return buildRootUrl() + "FORMAT=" + format + ((imageFormatHasTransparency(format) && transparent) ? "&TRANSPARENT=TRUE" : "")
+                + "&VERSION=" + this.version + "&SERVICE=WMS&REQUEST=GetMap&LAYERS="
+                + selectedLayers.stream().collect(Collectors.joining(","))
+                + "&STYLES="
+                + (selectedStyles != null ? Utils.join(",", selectedStyles) : "")
+                + "&"
+                + (belowWMS130() ? "SRS" : "CRS")
+                + "={proj}&WIDTH={width}&HEIGHT={height}&BBOX={bbox}";
+    }
+
+    private boolean tagEquals(QName a, QName b) {
+        boolean ret = a.equals(b);
+        if (ret) {
+            return ret;
+        }
+
+        if (belowWMS130()) {
+            return a.getLocalPart().equals(b.getLocalPart());
+        }
+
+        return false;
+    }
+
+    private void attemptGetCapabilities(String url) throws IOException, WMSGetCapabilitiesException {
+        Logging.debug("Trying WMS getcapabilities with url {0}", url);
+        try (CachedFile cf = new CachedFile(url); InputStream in = cf.setHttpHeaders(headers).
+                setMaxAge(7 * CachedFile.DAYS).
+                setCachingStrategy(CachedFile.CachingStrategy.IfModifiedSince).
+                getInputStream()) {
+
+            try {
+                XMLStreamReader reader = GetCapabilitiesParseHelper.getReader(in);
+                for (int event = reader.getEventType(); reader.hasNext(); event = reader.next()) {
+                    if (event == XMLStreamReader.START_ELEMENT) {
+                        if (tagEquals(CAPABILITIES_ROOT_111, reader.getName())) {
+                            // version 1.1.1
+                            this.version = reader.getAttributeValue(null, "version");
+                            if (this.version == null) {
+                                this.version = "1.1.1";
+                            }
+                        }
+                        if (tagEquals(CAPABILITITES_ROOT_130, reader.getName())) {
+                            this.version = reader.getAttributeValue(WMS_NS_URL, "version");
+                        }
+                        if (tagEquals(QN_SERVICE, reader.getName())) {
+                            parseService(reader);
+                        }
+
+                        if (tagEquals(QN_CAPABILITY, reader.getName())) {
+                            parseCapability(reader);
+                        }
+                    }
+                }
+            } catch (XMLStreamException e) {
+                String content = new String(cf.getByteContent(), UTF_8);
+                cf.clear(); // if there is a problem with parsing of the file, remove it from the cache
+                throw new WMSGetCapabilitiesException(e, content);
+            }
+        }
+    }
+
+    private void parseService(XMLStreamReader reader) throws XMLStreamException {
+        if (GetCapabilitiesParseHelper.moveReaderToTag(reader, this::tagEquals, QN_TITLE)) {
+            this.title = reader.getElementText();
+            for (int event = reader.getEventType();
+                    reader.hasNext() && !(event == XMLStreamReader.END_ELEMENT && tagEquals(QN_SERVICE, reader.getName()));
+                    event = reader.next()) {
+                // empty loop, just move reader to the end of Service tag, if moveReaderToTag return false, it's already done
+            }
+        }
+    }
+
+    private void parseCapability(XMLStreamReader reader) throws XMLStreamException {
+        for (int event = reader.getEventType();
+                reader.hasNext() && !(event == XMLStreamReader.END_ELEMENT && tagEquals(QN_CAPABILITY, reader.getName()));
+                event = reader.next()) {
+
+            if (event == XMLStreamReader.START_ELEMENT) {
+                if (tagEquals(QN_REQUEST, reader.getName())) {
+                    parseRequest(reader);
+                }
+                if (tagEquals(QN_LAYER, reader.getName())) {
+                    parseLayer(reader, null);
+                }
+            }
+        }
+    }
+
+    private void parseRequest(XMLStreamReader reader) throws XMLStreamException {
+        String mode = "";
+        String getMapUrl = "";
+        if (GetCapabilitiesParseHelper.moveReaderToTag(reader, this::tagEquals, QN_GETMAP)) {
+            for (int event = reader.getEventType();
+                    reader.hasNext() && !(event == XMLStreamReader.END_ELEMENT && tagEquals(QN_GETMAP, reader.getName()));
+                    event = reader.next()) {
+
+                if (event == XMLStreamReader.START_ELEMENT) {
+                    if (tagEquals(QN_FORMAT, reader.getName())) {
+                        String value = reader.getElementText();
+                        if (isImageFormatSupportedWarn(value) && !this.formats.contains(value)) {
+                            this.formats.add(value);
+                        }
+                    }
+                    if (tagEquals(QN_DCPTYPE, reader.getName()) && GetCapabilitiesParseHelper.moveReaderToTag(reader,
+                            this::tagEquals, QN_HTTP, QN_GET)) {
+                        mode = reader.getName().getLocalPart();
+                        if (GetCapabilitiesParseHelper.moveReaderToTag(reader, this::tagEquals, QN_ONLINE_RESOURCE)) {
+                            getMapUrl = reader.getAttributeValue(GetCapabilitiesParseHelper.XLINK_NS_URL, "href");
+                        }
+                        // TODO should we handle also POST?
+                        if ("GET".equalsIgnoreCase(mode) && getMapUrl != null && !"".equals(getMapUrl)) {
+                            this.getMapUrl = getMapUrl;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private void parseLayer(XMLStreamReader reader, LayerDetails parentLayer) throws XMLStreamException {
+        LayerDetails ret = new LayerDetails(parentLayer);
+        for (int event = reader.next(); // start with advancing reader by one element to get the contents of the layer
+                reader.hasNext() && !(event == XMLStreamReader.END_ELEMENT && tagEquals(QN_LAYER, reader.getName()));
+                event = reader.next()) {
+
+            if (event == XMLStreamReader.START_ELEMENT) {
+                if (tagEquals(QN_NAME, reader.getName())) {
+                    ret.setName(reader.getElementText());
+                }
+                if (tagEquals(QN_ABSTRACT, reader.getName())) {
+                    ret.setAbstract(GetCapabilitiesParseHelper.getElementTextWithSubtags(reader));
+                }
+                if (tagEquals(QN_TITLE, reader.getName())) {
+                    ret.setTitle(reader.getElementText());
+                }
+                if (tagEquals(QN_CRS, reader.getName())) {
+                    ret.addCrs(reader.getElementText());
+                }
+                if (tagEquals(QN_SRS, reader.getName()) && belowWMS130()) {
+                    ret.addCrs(reader.getElementText());
+                }
+                if (tagEquals(QN_STYLE, reader.getName())) {
+                    parseAndAddStyle(reader, ret);
+                }
+                if (tagEquals(QN_LAYER, reader.getName())) {
+
+                    parseLayer(reader, ret);
+                }
+                if (tagEquals(QN_EX_GEOGRAPHIC_BBOX, reader.getName())) {
+                    if (ret.getBounds() == null) {
+                        Bounds bbox = parseExGeographic(reader);
+                        ret.setBounds(bbox);
+                    }
+
+                }
+                if (tagEquals(QN_BOUNDINGBOX, reader.getName())) {
+                    Projection conv;
+                    if (belowWMS130()) {
+                        conv = Projections.getProjectionByCode(reader.getAttributeValue(WMS_NS_URL, "SRS"));
+                    } else {
+                        conv = Projections.getProjectionByCode(reader.getAttributeValue(WMS_NS_URL, "CRS"));
+                    }
+                    if (ret.getBounds() == null && conv != null) {
+                        Bounds bbox = parseBoundingBox(reader, conv);
+                        ret.setBounds(bbox);
+                    }
+                }
+                if (tagEquals(QN_LATLONBOUNDINGBOX, reader.getName()) && belowWMS130()) {
+                    if (ret.getBounds() == null) {
+                        Bounds bbox = parseBoundingBox(reader, null);
+                        ret.setBounds(bbox);
+                    }
+                }
+            }
+        }
+        this.layers.add(ret);
+    }
+
+    /**
+     * @return if this service operates at protocol level below 1.3.0
+     */
+    public boolean belowWMS130() {
+        return this.version.equals("1.1.1") || this.version.equals("1.1") || this.version.equals("1.0");
+    }
+
+    private void parseAndAddStyle(XMLStreamReader reader, LayerDetails ld) throws XMLStreamException {
+        String name = null;
+        String title = null;
+        for (int event = reader.getEventType();
+                reader.hasNext() && !(event == XMLStreamReader.END_ELEMENT && tagEquals(QN_STYLE, reader.getName()));
+                event = reader.next()) {
+            if (event == XMLStreamReader.START_ELEMENT) {
+                if (tagEquals(QN_NAME, reader.getName())) {
+                    name = reader.getElementText();
+                }
+                if (tagEquals(QN_TITLE, reader.getName())) {
+                    title = reader.getElementText();
+                }
+            }
+        }
+        if (name == null) {
+            name = "";
+        }
+        ld.addStyle(name, title);
+    }
+
+    private Bounds parseExGeographic(XMLStreamReader reader) throws XMLStreamException {
+        String minx = null, maxx = null, maxy = null, miny = null;
+
+        for (int event = reader.getEventType();
+                reader.hasNext() && !(event == XMLStreamReader.END_ELEMENT && tagEquals(QN_EX_GEOGRAPHIC_BBOX, reader.getName()));
+                event = reader.next()) {
+            if (event == XMLStreamReader.START_ELEMENT) {
+                if (tagEquals(QN_WESTBOUNDLONGITUDE, reader.getName())) {
+                    minx = reader.getElementText();
+                }
+
+                if (tagEquals(QN_EASTBOUNDLONGITUDE, reader.getName())) {
+                    maxx = reader.getElementText();
+                }
+
+                if (tagEquals(QN_SOUTHBOUNDLATITUDE, reader.getName())) {
+                    miny = reader.getElementText();
+                }
+
+                if (tagEquals(QN_NORTHBOUNDLATITUDE, reader.getName())) {
+                    maxy = reader.getElementText();
+                }
+            }
+        }
+        return parseBBox(null, miny, minx, maxy, maxx);
+    }
+
+    private Bounds parseBoundingBox(XMLStreamReader reader, Projection conv) {
+        Function<String, String> attrGetter = tag -> belowWMS130() ?
+                reader.getAttributeValue(null, tag)
+                : reader.getAttributeValue(WMS_NS_URL, tag);
+
+                return parseBBox(
+                        conv,
+                        attrGetter.apply("miny"),
+                        attrGetter.apply("minx"),
+                        attrGetter.apply("maxy"),
+                        attrGetter.apply("maxx")
+                        );
+    }
+
+    private Bounds parseBBox(Projection conv, String miny, String minx, String maxy, String maxx) {
+        if (miny == null || minx == null || maxy == null || maxx == null) {
+            return null;
+        }
+        if (conv != null) {
+            new Bounds(
+                    conv.eastNorth2latlon(new EastNorth(getDecimalDegree(minx), getDecimalDegree(miny))),
+                    conv.eastNorth2latlon(new EastNorth(getDecimalDegree(maxx), getDecimalDegree(maxy)))
+                    );
+        }
+        return new Bounds(
+                getDecimalDegree(miny),
+                getDecimalDegree(minx),
+                getDecimalDegree(maxy),
+                getDecimalDegree(maxx)
+                );
+    }
+
+    private static double getDecimalDegree(String value) {
+        // Some real-world WMS servers use a comma instead of a dot as decimal separator (seen in Polish WMS server)
+        return Double.parseDouble(value.replace(',', '.'));
+    }
+
+
+    private String normalizeUrl(String serviceUrlStr) throws MalformedURLException {
         URL getCapabilitiesUrl = null;
-        try {
-            if (!Pattern.compile(".*GetCapabilities.*", Pattern.CASE_INSENSITIVE).matcher(serviceUrlStr).matches()) {
-                // If the url doesn't already have GetCapabilities, add it in
-                getCapabilitiesUrl = new URL(serviceUrlStr);
-                final String getCapabilitiesQuery = "VERSION=1.1.1&SERVICE=WMS&REQUEST=GetCapabilities";
-                if (getCapabilitiesUrl.getQuery() == null) {
-                    getCapabilitiesUrl = new URL(serviceUrlStr + '?' + getCapabilitiesQuery);
-                } else if (!getCapabilitiesUrl.getQuery().isEmpty() && !getCapabilitiesUrl.getQuery().endsWith("&")) {
-                    getCapabilitiesUrl = new URL(serviceUrlStr + '&' + getCapabilitiesQuery);
-                } else {
-                    getCapabilitiesUrl = new URL(serviceUrlStr + getCapabilitiesQuery);
-                }
+        String ret = null;
+
+        if (!Pattern.compile(".*GetCapabilities.*", Pattern.CASE_INSENSITIVE).matcher(serviceUrlStr).matches()) {
+            // If the url doesn't already have GetCapabilities, add it in
+            getCapabilitiesUrl = new URL(serviceUrlStr);
+            ret = serviceUrlStr;
+            if (getCapabilitiesUrl.getQuery() == null) {
+                ret = serviceUrlStr + '?' + CAPABILITIES_QUERY_STRING;
+            } else if (!getCapabilitiesUrl.getQuery().isEmpty() && !getCapabilitiesUrl.getQuery().endsWith("&")) {
+                ret = serviceUrlStr + '&' + CAPABILITIES_QUERY_STRING;
             } else {
-                // Otherwise assume it's a good URL and let the subsequent error
-                // handling systems deal with problems
-                getCapabilitiesUrl = new URL(serviceUrlStr);
-            }
-            // Make sure we don't keep GetCapabilities request in service URL
-            serviceUrl = new URL(serviceUrlStr.replace("REQUEST=GetCapabilities", "").replace("&&", "&"));
-        } catch (HeadlessException e) {
-            Logging.warn(e);
-            return;
-        }
-
-        doAttemptGetCapabilities(serviceUrlStr, getCapabilitiesUrl);
-    }
-
-    /**
-     * Attempts WMS GetCapabilities with version 1.1.1 first, then 1.3.0 in case of specific errors.
-     * @param serviceUrlStr WMS service URL
-     * @param getCapabilitiesUrl GetCapabilities URL
-     * @throws IOException if any I/O error occurs
-     * @throws WMSGetCapabilitiesException if any HTTP or parsing error occurs
-     */
-    private void doAttemptGetCapabilities(String serviceUrlStr, URL getCapabilitiesUrl)
-            throws IOException, WMSGetCapabilitiesException {
-        final String url = getCapabilitiesUrl.toExternalForm();
-        final Response response = HttpClient.create(getCapabilitiesUrl).connect();
-
-        // Is the HTTP connection successul ?
-        if (response.getResponseCode() >= 400) {
-            // HTTP error for servers handling only WMS 1.3.0 ?
-            String errorMessage = response.getResponseMessage();
-            String errorContent = response.fetchContent();
-            Matcher tomcat = HttpClient.getTomcatErrorMatcher(errorContent);
-            boolean messageAbout130 = errorMessage != null && errorMessage.contains("1.3.0");
-            boolean contentAbout130 = errorContent != null && tomcat != null && tomcat.matches() && tomcat.group(1).contains("1.3.0");
-            if (url.contains("VERSION=1.1.1") && (messageAbout130 || contentAbout130)) {
-                doAttemptGetCapabilities130(serviceUrlStr, url);
-                return;
-            }
-            throw new WMSGetCapabilitiesException(errorMessage, errorContent);
-        }
-
-        try {
-            // Parse XML capabilities sent by the server
-            parseCapabilities(serviceUrlStr, response.getContent());
-        } catch (WMSGetCapabilitiesException e) {
-            // ServiceException for servers handling only WMS 1.3.0 ?
-            if (e.getCause() == null && url.contains("VERSION=1.1.1")) {
-                doAttemptGetCapabilities130(serviceUrlStr, url);
-            } else {
-                throw e;
-            }
-        }
-    }
-
-    /**
-     * Attempts WMS GetCapabilities with version 1.3.0.
-     * @param serviceUrlStr WMS service URL
-     * @param url GetCapabilities URL
-     * @throws IOException if any I/O error occurs
-     * @throws WMSGetCapabilitiesException if any HTTP or parsing error occurs
-     * @throws MalformedURLException in case of invalid URL
-     */
-    private void doAttemptGetCapabilities130(String serviceUrlStr, final String url)
-            throws IOException, WMSGetCapabilitiesException {
-        doAttemptGetCapabilities(serviceUrlStr, new URL(url.replace("VERSION=1.1.1", "VERSION=1.3.0")));
-        if (serviceUrl.toExternalForm().contains("VERSION=1.1.1")) {
-            serviceUrl = new URL(serviceUrl.toExternalForm().replace("VERSION=1.1.1", "VERSION=1.3.0"));
-        }
-        version = "1.3.0";
-    }
-
-    void parseCapabilities(String serviceUrlStr, InputStream contentStream) throws IOException, WMSGetCapabilitiesException {
-        String incomingData = null;
-        try {
-            DocumentBuilder builder = Utils.newSafeDOMBuilder();
-            builder.setEntityResolver((publicId, systemId) -> {
-                Logging.info("Ignoring DTD " + publicId + ", " + systemId);
-                return new InputSource(new StringReader(""));
-            });
-            Document document = builder.parse(contentStream);
-            Element root = document.getDocumentElement();
-
-            try {
-                StringWriter writer = new StringWriter();
-                TransformerFactory.newInstance().newTransformer().transform(new DOMSource(document), new StreamResult(writer));
-                incomingData = writer.getBuffer().toString();
-                Logging.debug("Server response to Capabilities request:");
-                Logging.debug(incomingData);
-            } catch (TransformerFactoryConfigurationError | TransformerException e) {
-                Logging.warn(e);
-            }
-
-            // Check if the request resulted in ServiceException
-            if ("ServiceException".equals(root.getTagName())) {
-                throw new WMSGetCapabilitiesException(root.getTextContent(), incomingData);
-            }
-
-            // Some WMS service URLs specify a different base URL for their GetMap service
-            Element child = getChild(root, "Capability");
-            child = getChild(child, "Request");
-            child = getChild(child, "GetMap");
-
-            formats = getChildrenStream(child, "Format")
-                    .map(Node::getTextContent)
-                    .filter(WMSImagery::isImageFormatSupportedWarn)
-                    .collect(Collectors.toList());
-
-            child = getChild(child, "DCPType");
-            child = getChild(child, "HTTP");
-            child = getChild(child, "Get");
-            child = getChild(child, "OnlineResource");
-            if (child != null) {
-                String baseURL = child.getAttributeNS(GetCapabilitiesParseHelper.XLINK_NS_URL, "href");
-                if (!baseURL.equals(serviceUrlStr)) {
-                    URL newURL = new URL(baseURL);
-                    if (newURL.getAuthority() != null) {
-                        Logging.info("GetCapabilities specifies a different service URL: " + baseURL);
-                        serviceUrl = newURL;
-                    }
-                }
-            }
-
-            Element capabilityElem = getChild(root, "Capability");
-            List<Element> children = getChildren(capabilityElem, "Layer");
-            layers = parseLayers(children, new HashSet<String>());
-        } catch (MalformedURLException | ParserConfigurationException | SAXException e) {
-            throw new WMSGetCapabilitiesException(e, incomingData);
-        }
+                ret = serviceUrlStr + CAPABILITIES_QUERY_STRING;
+            }
+        } else {
+            // Otherwise assume it's a good URL and let the subsequent error
+            // handling systems deal with problems
+            ret = serviceUrlStr;
+        }
+        return ret;
     }
 
@@ -392,4 +641,5 @@
     }
 
+
     static boolean imageFormatHasTransparency(final String format) {
         return format != null && (format.startsWith("image/png") || format.startsWith("image/gif")
@@ -398,219 +648,58 @@
 
     /**
-     * Returns a new {@code ImageryInfo} describing the given service name and selected WMS layers.
-     * @param name service name
-     * @param selectedLayers selected WMS layers
-     * @return a new {@code ImageryInfo} describing the given service name and selected WMS layers
-     */
-    public ImageryInfo toImageryInfo(String name, Collection<LayerDetails> selectedLayers) {
-        ImageryInfo i = new ImageryInfo(name, buildGetMapUrl(selectedLayers));
-        if (selectedLayers != null) {
-            Set<String> proj = new HashSet<>();
-            for (WMSImagery.LayerDetails l : selectedLayers) {
-                proj.addAll(l.getProjections());
-            }
-            i.setServerProjections(proj);
+     * Creates ImageryInfo object from this GetCapabilities document
+     *
+     * @param name name of imagery layer
+     * @param selectedLayers layers which are to be used by this imagery layer
+     * @param selectedStyles styles that should be used for selectedLayers
+     * @param transparent if layer should be transparent
+     * @return ImageryInfo object
+     */
+    public ImageryInfo toImageryInfo(String name, List<LayerDetails> selectedLayers, List<String> selectedStyles, boolean transparent) {
+        ImageryInfo i = new ImageryInfo(name, buildGetMapUrl(selectedLayers, selectedStyles, transparent));
+        if (selectedLayers != null && !selectedLayers.isEmpty()) {
+            i.setServerProjections(getServerProjections(selectedLayers));
         }
         return i;
     }
 
-    private List<LayerDetails> parseLayers(List<Element> children, Set<String> parentCrs) {
-        List<LayerDetails> details = new ArrayList<>(children.size());
-        for (Element element : children) {
-            details.add(parseLayer(element, parentCrs));
-        }
-        return details;
-    }
-
-    private LayerDetails parseLayer(Element element, Set<String> parentCrs) {
-        String name = getChildContent(element, "Title", null, null);
-        String ident = getChildContent(element, "Name", null, null);
-        String abstr = getChildContent(element, "Abstract", null, null);
-
-        // The set of supported CRS/SRS for this layer
-        Set<String> crsList = new HashSet<>();
-        // ...including this layer's already-parsed parent projections
-        crsList.addAll(parentCrs);
-
-        // Parse the CRS/SRS pulled out of this layer's XML element
-        // I think CRS and SRS are the same at this point
-        getChildrenStream(element)
-            .filter(child -> "CRS".equals(child.getNodeName()) || "SRS".equals(child.getNodeName()))
-            .map(WMSImagery::getContent)
-            .filter(crs -> !crs.isEmpty())
-            .map(crs -> crs.trim().toUpperCase(Locale.ENGLISH))
-            .forEach(crsList::add);
-
-        // Check to see if any of the specified projections are supported by JOSM
-        boolean josmSupportsThisLayer = false;
-        for (String crs : crsList) {
-            josmSupportsThisLayer |= isProjSupported(crs);
-        }
-
-        Bounds bounds = null;
-        Element bboxElem = getChild(element, "EX_GeographicBoundingBox");
-        if (bboxElem != null) {
-            // Attempt to use EX_GeographicBoundingBox for bounding box
-            double left = Double.parseDouble(getChildContent(bboxElem, "westBoundLongitude", null, null));
-            double top = Double.parseDouble(getChildContent(bboxElem, "northBoundLatitude", null, null));
-            double right = Double.parseDouble(getChildContent(bboxElem, "eastBoundLongitude", null, null));
-            double bot = Double.parseDouble(getChildContent(bboxElem, "southBoundLatitude", null, null));
-            bounds = new Bounds(bot, left, top, right);
-        } else {
-            // If that's not available, try LatLonBoundingBox
-            bboxElem = getChild(element, "LatLonBoundingBox");
-            if (bboxElem != null) {
-                double left = getDecimalDegree(bboxElem, "minx");
-                double top = getDecimalDegree(bboxElem, "maxy");
-                double right = getDecimalDegree(bboxElem, "maxx");
-                double bot = getDecimalDegree(bboxElem, "miny");
-                bounds = new Bounds(bot, left, top, right);
-            }
-        }
-
-        List<Element> layerChildren = getChildren(element, "Layer");
-        List<LayerDetails> childLayers = parseLayers(layerChildren, crsList);
-
-        return new LayerDetails(name, ident, abstr, crsList, josmSupportsThisLayer, bounds, childLayers);
-    }
-
-    private static double getDecimalDegree(Element elem, String attr) {
-        // Some real-world WMS servers use a comma instead of a dot as decimal separator (seen in Polish WMS server)
-        return Double.parseDouble(elem.getAttribute(attr).replace(',', '.'));
-    }
-
-    private static boolean isProjSupported(String crs) {
-        return Projections.getProjectionByCode(crs) != null;
-    }
-
-    private static String getChildContent(Element parent, String name, String missing, String empty) {
-        Element child = getChild(parent, name);
-        if (child == null)
-            return missing;
-        else {
-            String content = getContent(child);
-            return (!content.isEmpty()) ? content : empty;
-        }
-    }
-
-    private static String getContent(Element element) {
-        NodeList nl = element.getChildNodes();
-        StringBuilder content = new StringBuilder();
-        for (int i = 0; i < nl.getLength(); i++) {
-            Node node = nl.item(i);
-            switch (node.getNodeType()) {
-                case Node.ELEMENT_NODE:
-                    content.append(getContent((Element) node));
-                    break;
-                case Node.CDATA_SECTION_NODE:
-                case Node.TEXT_NODE:
-                    content.append(node.getNodeValue());
-                    break;
-                default: // Do nothing
-            }
-        }
-        return content.toString().trim();
-    }
-
-    private static Stream<Element> getChildrenStream(Element parent) {
-        if (parent == null) {
-            // ignore missing elements
-            return Stream.empty();
-        } else {
-            Iterable<Element> it = () -> new ChildIterator(parent);
-            return StreamSupport.stream(it.spliterator(), false);
-        }
-    }
-
-    private static Stream<Element> getChildrenStream(Element parent, String name) {
-        return getChildrenStream(parent).filter(child -> name.equals(child.getNodeName()));
-    }
-
-    private static List<Element> getChildren(Element parent, String name) {
-        return getChildrenStream(parent, name).collect(Collectors.toList());
-    }
-
-    private static Element getChild(Element parent, String name) {
-        return getChildrenStream(parent, name).findFirst().orElse(null);
-    }
-
-    /**
-     * The details of a layer of this WMS server.
-     */
-    public static class LayerDetails {
-
-        /**
-         * The layer name (WMS {@code Title})
-         */
-        public final String name;
-        /**
-         * The layer ident (WMS {@code Name})
-         */
-        public final String ident;
-        /**
-         * The layer abstract (WMS {@code Abstract})
-         * @since 13199
-         */
-        public final String abstr;
-        /**
-         * The child layers of this layer
-         */
-        public final List<LayerDetails> children;
-        /**
-         * The bounds this layer can be used for
-         */
-        public final Bounds bounds;
-        /**
-         * the CRS/SRS pulled out of this layer's XML element
-         */
-        public final Set<String> crsList;
-        /**
-         * {@code true} if any of the specified projections are supported by JOSM
-         */
-        public final boolean supported;
-
-        /**
-         * Constructs a new {@code LayerDetails}.
-         * @param name The layer name (WMS {@code Title})
-         * @param ident The layer ident (WMS {@code Name})
-         * @param abstr The layer abstract (WMS {@code Abstract})
-         * @param crsList The CRS/SRS pulled out of this layer's XML element
-         * @param supportedLayer {@code true} if any of the specified projections are supported by JOSM
-         * @param bounds The bounds this layer can be used for
-         * @param childLayers The child layers of this layer
-         * @since 13199
-         */
-        public LayerDetails(String name, String ident, String abstr, Set<String> crsList, boolean supportedLayer, Bounds bounds,
-                List<LayerDetails> childLayers) {
-            this.name = name;
-            this.ident = ident;
-            this.abstr = abstr;
-            this.supported = supportedLayer;
-            this.children = childLayers;
-            this.bounds = bounds;
-            this.crsList = crsList;
-        }
-
-        /**
-         * Determines if any of the specified projections are supported by JOSM.
-         * @return {@code true} if any of the specified projections are supported by JOSM
-         */
-        public boolean isSupported() {
-            return this.supported;
-        }
-
-        /**
-         * Returns the CRS/SRS pulled out of this layer's XML element.
-         * @return the CRS/SRS pulled out of this layer's XML element
-         */
-        public Set<String> getProjections() {
-            return crsList;
-        }
-
-        @Override
-        public String toString() {
-            String baseName = (name == null || name.isEmpty()) ? ident : name;
-            return abstr == null || abstr.equalsIgnoreCase(baseName) ? baseName : baseName + " (" + abstr + ')';
-        }
+    /**
+     * Returns projections that server supports for provided list of layers. This will be intersection of projections
+     * defined for each layer
+     *
+     * @param selectedLayers list of layers
+     * @return projection code
+     */
+    public Collection<String> getServerProjections(List<LayerDetails> selectedLayers) {
+        if (selectedLayers.isEmpty()) {
+            return Collections.emptyList();
+        }
+        Set<String> proj = new HashSet<>(selectedLayers.get(0).getCrs());
+
+        // set intersect with all layers
+        for (LayerDetails ld: selectedLayers) {
+            proj.retainAll(ld.getCrs());
+        }
+        return proj;
+    }
+
+
+    /**
+     * @param defaultLayers
+     * @return collection of LayerDetails specified by DefaultLayers
+     */
+    public List<LayerDetails> getLayers(List<DefaultLayer> defaultLayers) {
+        Collection<String> layerNames = defaultLayers.stream().map(x -> x.getLayerName()).collect(Collectors.toList());
+        return layers.stream()
+                .flatMap(LayerDetails::flattened)
+                .filter(x -> layerNames.contains(x.getName()))
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * @return title of this service
+     */
+    public String getTitle() {
+        return title;
     }
 }
Index: /trunk/test/data/regress/15730/capabilities.xml
===================================================================
--- /trunk/test/data/regress/15730/capabilities.xml	(revision 13732)
+++ /trunk/test/data/regress/15730/capabilities.xml	(revision 13733)
Index: /trunk/test/data/wms/geofabrik-osm-inspector.xml
===================================================================
--- /trunk/test/data/wms/geofabrik-osm-inspector.xml	(revision 13733)
+++ /trunk/test/data/wms/geofabrik-osm-inspector.xml	(revision 13733)
@@ -0,0 +1,367 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<WMS_Capabilities version="1.3.0" xmlns="http://www.opengis.net/wms" xmlns:sld="http://www.opengis.net/sld" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ms="http://mapserver.gis.umn.edu/mapserver" xsi:schemaLocation="http://www.opengis.net/wms http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xsd  http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/sld_capabilities.xsd  http://mapserver.gis.umn.edu/mapserver https://tools.geofabrik.de/osmi/views/geometry/wxs?service=WMS&amp;version=1.3.0&amp;request=GetSchemaExtension">
+
+<!-- MapServer version 7.0.0 OUTPUT=PNG OUTPUT=JPEG SUPPORTS=PROJ SUPPORTS=AGG SUPPORTS=FREETYPE SUPPORTS=CAIRO SUPPORTS=ICONV SUPPORTS=FRIBIDI SUPPORTS=WMS_SERVER SUPPORTS=WFS_SERVER SUPPORTS=WCS_SERVER SUPPORTS=FASTCGI SUPPORTS=GEOS INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE -->
+
+<Service>
+  <Name>WMS</Name>
+  <Title>Geofabrik Tools: OSM Inspector (Geometry)</Title>
+  <Abstract>OSM Inspector is a debugging tool for OpenStreetMap data.</Abstract>
+  <KeywordList>
+      <Keyword>Geofabrik</Keyword>
+      <Keyword>OpenStreetMap</Keyword>
+      <Keyword>OSM</Keyword>
+      <Keyword>OSM Inspector</Keyword>
+  </KeywordList>
+  <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://tools.geofabrik.de/osmi/views/geometry/wxs?"/>
+  <ContactInformation>
+    <ContactPersonPrimary>
+      <ContactPerson>Jochen Topf</ContactPerson>
+      <ContactOrganization>Geofabrik GmbH</ContactOrganization>
+    </ContactPersonPrimary>
+      <ContactVoiceTelephone>+49-721-1803560-0</ContactVoiceTelephone>
+  <ContactElectronicMailAddress>info@geofabrik.de</ContactElectronicMailAddress>
+  </ContactInformation>
+  <MaxWidth>2048</MaxWidth>
+  <MaxHeight>2048</MaxHeight>
+</Service>
+
+<Capability>
+  <Request>
+    <GetCapabilities>
+      <Format>text/xml</Format>
+      <DCPType>
+        <HTTP>
+          <Get><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://tools.geofabrik.de/osmi/views/geometry/wxs?"/></Get>
+          <Post><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://tools.geofabrik.de/osmi/views/geometry/wxs?"/></Post>
+        </HTTP>
+      </DCPType>
+    </GetCapabilities>
+    <GetMap>
+      <Format>image/png</Format>
+      <Format>image/jpeg</Format>
+      <Format>image/png; mode=8bit</Format>
+      <Format>application/x-pdf</Format>
+      <Format>image/svg+xml</Format>
+      <Format>image/tiff</Format>
+      <DCPType>
+        <HTTP>
+          <Get><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://tools.geofabrik.de/osmi/views/geometry/wxs?"/></Get>
+          <Post><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://tools.geofabrik.de/osmi/views/geometry/wxs?"/></Post>
+        </HTTP>
+      </DCPType>
+    </GetMap>
+    <GetFeatureInfo>
+      <Format>text/html</Format>
+      <Format>application/vnd.ogc.gml</Format>
+      <Format>text/plain</Format>
+      <DCPType>
+        <HTTP>
+          <Get><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://tools.geofabrik.de/osmi/views/geometry/wxs?"/></Get>
+          <Post><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://tools.geofabrik.de/osmi/views/geometry/wxs?"/></Post>
+        </HTTP>
+      </DCPType>
+    </GetFeatureInfo>
+    <sld:DescribeLayer>
+      <Format>text/xml</Format>
+      <DCPType>
+        <HTTP>
+          <Get><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://tools.geofabrik.de/osmi/views/geometry/wxs?"/></Get>
+          <Post><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://tools.geofabrik.de/osmi/views/geometry/wxs?"/></Post>
+        </HTTP>
+      </DCPType>
+    </sld:DescribeLayer>
+    <sld:GetLegendGraphic>
+      <Format>image/png</Format>
+      <Format>image/jpeg</Format>
+      <Format>image/png; mode=8bit</Format>
+      <DCPType>
+        <HTTP>
+          <Get><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://tools.geofabrik.de/osmi/views/geometry/wxs?"/></Get>
+          <Post><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://tools.geofabrik.de/osmi/views/geometry/wxs?"/></Post>
+        </HTTP>
+      </DCPType>
+    </sld:GetLegendGraphic>
+    <ms:GetStyles>
+      <Format>text/xml</Format>
+      <DCPType>
+        <HTTP>
+          <Get><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://tools.geofabrik.de/osmi/views/geometry/wxs?"/></Get>
+          <Post><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://tools.geofabrik.de/osmi/views/geometry/wxs?"/></Post>
+        </HTTP>
+      </DCPType>
+    </ms:GetStyles>
+  </Request>
+  <Exception>
+    <Format>XML</Format>
+    <Format>INIMAGE</Format>
+    <Format>BLANK</Format>
+  </Exception>
+  <sld:UserDefinedSymbolization SupportSLD="1" UserLayer="0" UserStyle="1" RemoteWFS="0" InlineFeature="0" RemoteWCS="0"/>
+  <Layer>
+    <Name>geofabrik_tools_osminspector_geometry</Name>
+    <Title>Geofabrik Tools: OSM Inspector (Geometry)</Title>
+    <Abstract>OSM Inspector is a debugging tool for OpenStreetMap data.</Abstract>
+    <KeywordList>
+        <Keyword>Geofabrik</Keyword>
+        <Keyword>OpenStreetMap</Keyword>
+        <Keyword>OSM</Keyword>
+        <Keyword>OSM Inspector</Keyword>
+    </KeywordList>
+    <CRS>EPSG:4326</CRS>
+    <CRS>EPSG:900913</CRS>
+    <EX_GeographicBoundingBox>
+        <westBoundLongitude>-180</westBoundLongitude>
+        <eastBoundLongitude>180</eastBoundLongitude>
+        <southBoundLatitude>-83</southBoundLatitude>
+        <northBoundLatitude>83</northBoundLatitude>
+    </EX_GeographicBoundingBox>
+    <BoundingBox CRS="EPSG:900913" minx="-2.00375e+07" miny="-1.78219e+07" maxx="2.00375e+07" maxy="1.78219e+07"/>
+    <Attribution>
+        <Title>Geofabrik GmbH/OpenStreetMap Contributors</Title>
+        <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.geofabrik.de/"/>
+    </Attribution>
+    <Layer queryable="1" opaque="0" cascaded="0">
+        <Name>long_segments</Name>
+        <Title>Long segments</Title>
+        <Abstract>Segments (direct connection between two nodes in a way) longer than 20 km.</Abstract>
+        <KeywordList>
+            <Keyword>datasrc=OSM</Keyword>
+            <Keyword>min=2</Keyword>
+            <Keyword>max=22</Keyword>
+        </KeywordList>
+        <CRS>EPSG:4326</CRS>
+        <CRS>EPSG:900913</CRS>
+        <EX_GeographicBoundingBox>
+            <westBoundLongitude>-180</westBoundLongitude>
+            <eastBoundLongitude>180</eastBoundLongitude>
+            <southBoundLatitude>-89</southBoundLatitude>
+            <northBoundLatitude>84.6946</northBoundLatitude>
+        </EX_GeographicBoundingBox>
+        <BoundingBox CRS="EPSG:4326" minx="-89" miny="-180" maxx="84.6946" maxy="180"/>
+        <Style>
+          <Name>default</Name>
+          <Title>default</Title>
+          <LegendURL width="123" height="23">
+             <Format>image/png</Format>
+             <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="https://tools.geofabrik.de/osmi/views/geometry/wxs?version=1.3.0&amp;service=WMS&amp;request=GetLegendGraphic&amp;sld_version=1.1.0&amp;layer=long_segments&amp;format=image/png&amp;STYLE=default"/>
+          </LegendURL>
+        </Style>
+        <MinScaleDenominator>1</MinScaleDenominator>
+        <MaxScaleDenominator>2e+08</MaxScaleDenominator>
+    </Layer>
+    <Layer queryable="1" opaque="0" cascaded="0">
+        <Name>ways_with_long_segments</Name>
+        <Title>Ways with long segments</Title>
+        <Abstract>Ways containing segments longer than 20 km.</Abstract>
+        <KeywordList>
+            <Keyword>datasrc=OSM</Keyword>
+            <Keyword>min=2</Keyword>
+            <Keyword>max=22</Keyword>
+            <Keyword>label=tags</Keyword>
+            <Keyword>labelmin=10</Keyword>
+            <Keyword>labelmax=22</Keyword>
+        </KeywordList>
+        <CRS>EPSG:4326</CRS>
+        <CRS>EPSG:900913</CRS>
+        <EX_GeographicBoundingBox>
+            <westBoundLongitude>-180</westBoundLongitude>
+            <eastBoundLongitude>180</eastBoundLongitude>
+            <southBoundLatitude>-89</southBoundLatitude>
+            <northBoundLatitude>84.6946</northBoundLatitude>
+        </EX_GeographicBoundingBox>
+        <BoundingBox CRS="EPSG:4326" minx="-89" miny="-180" maxx="84.6946" maxy="180"/>
+        <Style>
+          <Name>default</Name>
+          <Title>default</Title>
+          <LegendURL width="190" height="23">
+             <Format>image/png</Format>
+             <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="https://tools.geofabrik.de/osmi/views/geometry/wxs?version=1.3.0&amp;service=WMS&amp;request=GetLegendGraphic&amp;sld_version=1.1.0&amp;layer=ways_with_long_segments&amp;format=image/png&amp;STYLE=default"/>
+          </LegendURL>
+        </Style>
+        <MinScaleDenominator>1</MinScaleDenominator>
+        <MaxScaleDenominator>2e+08</MaxScaleDenominator>
+    </Layer>
+    <Layer queryable="1" opaque="0" cascaded="0">
+        <Name>long_ways</Name>
+        <Title>Long ways</Title>
+        <Abstract>Ways with more than 1900 nodes. The API allows a way to have up to 2000 nodes, but shorter ways are easier to edit.</Abstract>
+        <KeywordList>
+            <Keyword>datasrc=OSM</Keyword>
+            <Keyword>min=4</Keyword>
+            <Keyword>max=22</Keyword>
+            <Keyword>label=tags</Keyword>
+            <Keyword>labelmin=10</Keyword>
+            <Keyword>labelmax=22</Keyword>
+        </KeywordList>
+        <CRS>EPSG:4326</CRS>
+        <CRS>EPSG:900913</CRS>
+        <EX_GeographicBoundingBox>
+            <westBoundLongitude>-176.788</westBoundLongitude>
+            <eastBoundLongitude>176.947</eastBoundLongitude>
+            <southBoundLatitude>-83.335</southBoundLatitude>
+            <northBoundLatitude>82.9911</northBoundLatitude>
+        </EX_GeographicBoundingBox>
+        <BoundingBox CRS="EPSG:4326" minx="-83.335" miny="-176.788" maxx="82.9911" maxy="176.947"/>
+        <Style>
+          <Name>default</Name>
+          <Title>default</Title>
+          <LegendURL width="96" height="23">
+             <Format>image/png</Format>
+             <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="https://tools.geofabrik.de/osmi/views/geometry/wxs?version=1.3.0&amp;service=WMS&amp;request=GetLegendGraphic&amp;sld_version=1.1.0&amp;layer=long_ways&amp;format=image/png&amp;STYLE=default"/>
+          </LegendURL>
+        </Style>
+        <MinScaleDenominator>1</MinScaleDenominator>
+        <MaxScaleDenominator>1e+08</MaxScaleDenominator>
+    </Layer>
+    <Layer queryable="1" opaque="0" cascaded="0">
+        <Name>single_node_in_way</Name>
+        <Title>Way with single node</Title>
+        <Abstract>Ways containing just a single node. This should not happen and needs to be fixed.</Abstract>
+        <KeywordList>
+            <Keyword>datasrc=OSM</Keyword>
+            <Keyword>min=3</Keyword>
+            <Keyword>max=22</Keyword>
+            <Keyword>label=tags</Keyword>
+            <Keyword>labelmin=10</Keyword>
+            <Keyword>labelmax=22</Keyword>
+        </KeywordList>
+        <CRS>EPSG:4326</CRS>
+        <CRS>EPSG:900913</CRS>
+        <EX_GeographicBoundingBox>
+            <westBoundLongitude>-9.37981</westBoundLongitude>
+            <eastBoundLongitude>112.258</eastBoundLongitude>
+            <southBoundLatitude>14.8906</southBoundLatitude>
+            <northBoundLatitude>53.8984</northBoundLatitude>
+        </EX_GeographicBoundingBox>
+        <BoundingBox CRS="EPSG:4326" minx="14.8906" miny="-9.37981" maxx="53.8984" maxy="112.258"/>
+        <Style>
+          <Name>default</Name>
+          <Title>default</Title>
+          <LegendURL width="151" height="23">
+             <Format>image/png</Format>
+             <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="https://tools.geofabrik.de/osmi/views/geometry/wxs?version=1.3.0&amp;service=WMS&amp;request=GetLegendGraphic&amp;sld_version=1.1.0&amp;layer=single_node_in_way&amp;format=image/png&amp;STYLE=default"/>
+          </LegendURL>
+        </Style>
+        <MinScaleDenominator>1</MinScaleDenominator>
+        <MaxScaleDenominator>1e+08</MaxScaleDenominator>
+    </Layer>
+    <Layer queryable="1" opaque="0" cascaded="0">
+        <Name>duplicate_node_in_way</Name>
+        <Title>Way with duplicate node</Title>
+        <Abstract>Ways containing a node twice (or more times) right next to each other. This should not happen and needs to be fixed. Subsequent nodes with the same location (but different ID) are flagged as errors, too.</Abstract>
+        <KeywordList>
+            <Keyword>datasrc=OSM</Keyword>
+            <Keyword>min=4</Keyword>
+            <Keyword>max=22</Keyword>
+        </KeywordList>
+        <CRS>EPSG:4326</CRS>
+        <CRS>EPSG:900913</CRS>
+        <EX_GeographicBoundingBox>
+            <westBoundLongitude>-175.067</westBoundLongitude>
+            <eastBoundLongitude>174.828</eastBoundLongitude>
+            <southBoundLatitude>-45.9067</southBoundLatitude>
+            <northBoundLatitude>73.4486</northBoundLatitude>
+        </EX_GeographicBoundingBox>
+        <BoundingBox CRS="EPSG:4326" minx="-45.9067" miny="-175.067" maxx="73.4486" maxy="174.828"/>
+        <Style>
+          <Name>default</Name>
+          <Title>default</Title>
+          <LegendURL width="170" height="23">
+             <Format>image/png</Format>
+             <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="https://tools.geofabrik.de/osmi/views/geometry/wxs?version=1.3.0&amp;service=WMS&amp;request=GetLegendGraphic&amp;sld_version=1.1.0&amp;layer=duplicate_node_in_way&amp;format=image/png&amp;STYLE=default"/>
+          </LegendURL>
+        </Style>
+        <MinScaleDenominator>1</MinScaleDenominator>
+        <MaxScaleDenominator>5e+07</MaxScaleDenominator>
+    </Layer>
+    <Layer queryable="1" opaque="0" cascaded="0">
+        <Name>duplicate_node_in_way_way</Name>
+        <Title>Way with duplicate node</Title>
+        <Abstract>Ways containing a node twice (or more times) right next to each other. This should not happen and needs to be fixed. Subsequent nodes with the same location (but different ID) are flagged as errors, too.</Abstract>
+        <KeywordList>
+            <Keyword>datasrc=OSM</Keyword>
+            <Keyword>min=12</Keyword>
+            <Keyword>max=22</Keyword>
+        </KeywordList>
+        <CRS>EPSG:4326</CRS>
+        <CRS>EPSG:900913</CRS>
+        <EX_GeographicBoundingBox>
+            <westBoundLongitude>-175.067</westBoundLongitude>
+            <eastBoundLongitude>174.829</eastBoundLongitude>
+            <southBoundLatitude>-45.907</southBoundLatitude>
+            <northBoundLatitude>73.4615</northBoundLatitude>
+        </EX_GeographicBoundingBox>
+        <BoundingBox CRS="EPSG:4326" minx="-45.907" miny="-175.067" maxx="73.4615" maxy="174.829"/>
+        <Style>
+          <Name>default</Name>
+          <Title>default</Title>
+          <LegendURL width="170" height="23">
+             <Format>image/png</Format>
+             <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="https://tools.geofabrik.de/osmi/views/geometry/wxs?version=1.3.0&amp;service=WMS&amp;request=GetLegendGraphic&amp;sld_version=1.1.0&amp;layer=duplicate_node_in_way_way&amp;format=image/png&amp;STYLE=default"/>
+          </LegendURL>
+        </Style>
+        <MinScaleDenominator>1</MinScaleDenominator>
+        <MaxScaleDenominator>200000</MaxScaleDenominator>
+    </Layer>
+    <Layer queryable="1" opaque="0" cascaded="0">
+        <Name>self_intersection_ways</Name>
+        <Title>Self-intersecting ways</Title>
+        <Abstract>Ways that touch or intersect themselves. Only closed ways (where first and last nodes are the same) are tested. In most cases ways should not self-intersect, but there could be cases where it is ok. Check the tags before fixing.</Abstract>
+        <KeywordList>
+            <Keyword>datasrc=OSM</Keyword>
+            <Keyword>min=6</Keyword>
+            <Keyword>max=22</Keyword>
+        </KeywordList>
+        <CRS>EPSG:4326</CRS>
+        <CRS>EPSG:900913</CRS>
+        <EX_GeographicBoundingBox>
+            <westBoundLongitude>-179.999</westBoundLongitude>
+            <eastBoundLongitude>180</eastBoundLongitude>
+            <southBoundLatitude>-85.0546</southBoundLatitude>
+            <northBoundLatitude>87.0001</northBoundLatitude>
+        </EX_GeographicBoundingBox>
+        <BoundingBox CRS="EPSG:4326" minx="-85.0546" miny="-179.999" maxx="87.0001" maxy="180"/>
+        <Style>
+          <Name>default</Name>
+          <Title>default</Title>
+          <LegendURL width="65" height="20">
+             <Format>image/png</Format>
+             <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="https://tools.geofabrik.de/osmi/views/geometry/wxs?version=1.3.0&amp;service=WMS&amp;request=GetLegendGraphic&amp;sld_version=1.1.0&amp;layer=self_intersection_ways&amp;format=image/png&amp;STYLE=default"/>
+          </LegendURL>
+        </Style>
+        <MinScaleDenominator>1</MinScaleDenominator>
+        <MaxScaleDenominator>1.25e+07</MaxScaleDenominator>
+    </Layer>
+    <Layer queryable="1" opaque="0" cascaded="0">
+        <Name>self_intersection_points</Name>
+        <Title>Intersection points</Title>
+        <Abstract>Points where a way intersects itself.</Abstract>
+        <KeywordList>
+            <Keyword>datasrc=OSM</Keyword>
+            <Keyword>min=10</Keyword>
+            <Keyword>max=22</Keyword>
+        </KeywordList>
+        <CRS>EPSG:4326</CRS>
+        <CRS>EPSG:900913</CRS>
+        <EX_GeographicBoundingBox>
+            <westBoundLongitude>-179.989</westBoundLongitude>
+            <eastBoundLongitude>179.968</eastBoundLongitude>
+            <southBoundLatitude>-85.0542</southBoundLatitude>
+            <northBoundLatitude>87.0001</northBoundLatitude>
+        </EX_GeographicBoundingBox>
+        <BoundingBox CRS="EPSG:4326" minx="-85.0542" miny="-179.989" maxx="87.0001" maxy="179.968"/>
+        <Style>
+          <Name>default</Name>
+          <Title>default</Title>
+          <LegendURL width="111" height="20">
+             <Format>image/png</Format>
+             <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="https://tools.geofabrik.de/osmi/views/geometry/wxs?version=1.3.0&amp;service=WMS&amp;request=GetLegendGraphic&amp;sld_version=1.1.0&amp;layer=self_intersection_points&amp;format=image/png&amp;STYLE=default"/>
+          </LegendURL>
+        </Style>
+        <MinScaleDenominator>1</MinScaleDenominator>
+        <MaxScaleDenominator>750000</MaxScaleDenominator>
+    </Layer>
+  </Layer>
+</Capability>
+</WMS_Capabilities>
Index: /trunk/test/data/wms/mapa-um-warszawa-pl.xml
===================================================================
--- /trunk/test/data/wms/mapa-um-warszawa-pl.xml	(revision 13733)
+++ /trunk/test/data/wms/mapa-um-warszawa-pl.xml	(revision 13733)
@@ -0,0 +1,5105 @@
+
+
+  <!DOCTYPE WMT_MS_Capabilities SYSTEM
+ "http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd"
+  [
+   <!ELEMENT VendorSpecificCapabilities EMPTY>
+  ]>
+  <WMT_MS_Capabilities version="1.1.1">
+   <!--
+
+   SERVICE METADATA
+
+   -->
+   <Service>
+    <Name>OGC:WMS</Name>
+    <Title>Server WMS m.st. Warszawy</Title>
+    
+    <Abstract>Server WMS m.st. Warszawy</Abstract>
+    
+    
+    <KeywordList>
+     <Keyword>GIS</Keyword>
+ <Keyword>WMS</Keyword>
+ <Keyword>Server</Keyword>
+ 
+    </KeywordList>
+    
+    <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://wms.um.warszawa.pl/"></OnlineResource>
+
+    <ContactInformation>
+     <ContactPersonPrimary>
+      <ContactPerson>Urząd m.st. Warszawy</ContactPerson>
+      <ContactOrganization>Urząd m.st. Warszawy</ContactOrganization>
+     </ContactPersonPrimary>
+     
+     
+     <ContactAddress>
+      <AddressType>postal</AddressType>
+      <Address>Sandomierska 12</Address>
+      <City>Warszawa</City>
+      <StateOrProvince>mazowieckie</StateOrProvince>
+      <PostCode></PostCode>
+      <Country>Polska</Country>
+     </ContactAddress>
+     
+     
+     
+     
+     <ContactElectronicMailAddress>ortofoto@um.warszawa.pl</ContactElectronicMailAddress>
+     
+    </ContactInformation>
+
+    <Fees>opłaty zgodnie z prawem</Fees>
+    <AccessConstraints>none</AccessConstraints>
+   </Service>
+
+   <!--
+
+   SERVICE CAPABILITIES
+
+   -->
+   <Capability>
+
+    <Request>
+     <GetCapabilities>
+      
+  <Format>text/xml</Format>
+ 
+  <Format>text/html</Format>
+ 
+  <Format>application/vnd.ogc.wms_xml</Format>
+ 
+      <DCPType>
+       <HTTP>
+        <Get>
+        <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://wms.um.warszawa.pl/serwis?"/>
+        </Get>
+       </HTTP>
+      </DCPType>
+     </GetCapabilities>
+
+     <GetMap>
+      
+  <Format>image/png</Format>
+ 
+  <Format>image/jpeg</Format>
+ 
+  <Format>image/gif</Format>
+ 
+      <DCPType>
+       <HTTP>
+        <Get>
+        <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://wms.um.warszawa.pl/serwis?"/>
+        </Get>
+       </HTTP>
+      </DCPType>
+     </GetMap>
+
+     <GetFeatureInfo>
+      
+  <Format>text/xml</Format>
+ 
+  <Format>text/html</Format>
+ 
+  <Format>text/plain</Format>
+ 
+      <DCPType>
+       <HTTP>
+        <Get>
+        <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://wms.um.warszawa.pl/serwis?"/>
+        </Get>
+       </HTTP>
+      </DCPType>
+     </GetFeatureInfo>
+
+    </Request>
+
+    <Exception>
+     
+  <Format>application/vnd.ogc.se_xml</Format>
+ 
+    </Exception>
+
+    <!-- No VendorSpecificCapabilities -->
+    <!-- No UserDefinedSymbolization -->
+
+    <!--
+
+    PUBLISHED LAYERS
+
+    -->
+    <Layer>
+     <Title>Server WMS m.st. Warszawy</Title>
+     <SRS>EPSG:4326</SRS>
+     <LatLonBoundingBox minx="-180" miny="-90" maxx="180" maxy="90"/>
+     
+  <!-- Published Layer #1 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2012_8m</Name>
+   <Title>Raster - Fotoplan 2012 - piksel 8m</Title>
+   <Abstract>Fotoplan z 2012 roku z pikselem 8m dla zakresu skal od 1:60000 do 1:30000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #2 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2012_10cm</Name>
+   <Title>Raster - Fotoplan 2012 - piksel 10cm</Title>
+   <Abstract>Fotoplan z 2012 roku z pikselem 10cm dla zakresu skal od 0 do 1:15000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #3 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Cmentarze_kwatery</Name>
+   <Title>Religia - Cmentarze - Kwatery</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #4 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Historia_granica_1992</Name>
+   <Title>Historia - Granica Warszawy 1992</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #5 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Historia_granica1939_1945</Name>
+   <Title>Historia - Granica Warszawy 1945 (dekretowa)</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #6 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Inne_Obszary_ogr_uzytk</Name>
+   <Title>Inne - Obszar ograniczonego użytkowania</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #7 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Inne_Strefa_Z1</Name>
+   <Title>Inne - Strefa ograniczeń zabudowy</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #8 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Komunikacja_koleje_glowne</Name>
+   <Title>Komunikacja - Linie kolejowe</Title>
+   <Abstract>Główne linie kolejowe</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #9 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Komunikacja_Metro_wejscia</Name>
+   <Title>Komunikacje - Wejścia do Metra</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #10 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Komunikacja_PrzystankiSKM</Name>
+   <Title>Komunikacja - Przystanki SKM</Title>
+   <Abstract>Przystanki Szybkiej Kolei Miejskiej</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #11 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Komunikacja_PrzystankiWKD</Name>
+   <Title>Komunikacja - Przystanki WKD</Title>
+   <Abstract>Przystanki Warszawskiej Kolei Dojazdowej</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #12 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Komunikacja_PrzystankiZTM</Name>
+   <Title>Komunikacja - Przystanki ZTM</Title>
+   <Abstract>Przystanki autobusowe i tramwajowe</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #13 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Komunikacja_StacjeMetro</Name>
+   <Title>Komunikacja - Stacje Metra</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #14 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Komunikacja_Strefa_płatnego_parkowania</Name>
+   <Title>Komunikacja - Strefa płatnego parkowania</Title>
+   <Abstract>Strefa płatnego parkowania</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #15 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Komunikacja_Tramwaje</Name>
+   <Title>Komunikacja - Linie tramwajowe</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #16 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Kultura_Biblioteki</Name>
+   <Title>Kultura - Biblioteki</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #17 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Kultura_Domy_kultury</Name>
+   <Title>Kultura - Domy Kultury</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #18 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Kultura_Kina</Name>
+   <Title>Kultura - Kina</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #19 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Kultura_Muzea</Name>
+   <Title>Kultura - Muzea</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #20 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Kultura_Teatry</Name>
+   <Title>Kultura - Teatry</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #21 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Nieruchomosci_na_sprzedaz_ogloszone</Name>
+   <Title>Nieruchomości na sprzedaż - przetargi ogłoszone</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #22 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Nieruchomosci_na_sprzedaz_planowane</Name>
+   <Title>Nieruchomości na sprzedaż - planowane do zbycia</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #23 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Nieruchomosci_na_sprzedaz_przygotowywane</Name>
+   <Title>Nieruchomości na sprzedaż - przeznaczone do zbycia</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #24 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/OpiekaSpoleczna_osrodki_pomocy_spolecznej</Name>
+   <Title>Opieka Społeczna - Ośrodki Pomocy Społecznej</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #25 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/OpiekaZdrowotna_placowki_terapii_uzaleznien</Name>
+   <Title>Opieka Zdrowotna - Placówki Terapii Uzależnień</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #26 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2011_10cm</Name>
+   <Title>Raster - Fotoplan 2011 - piksel 10cm</Title>
+   <Abstract>Fotoplan z 2011 roku z pikselem 10cm dla zakresu skal od 0 do 1:15000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #27 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2011_16m</Name>
+   <Title>Raster - Fotoplan 2011 - piksel 16m</Title>
+   <Abstract>Fotoplan z 2011 roku z pikselem 16m dla zakresu skal od 1:120000 do 1:60000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #28 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2011_32m</Name>
+   <Title>Raster - Fotoplan 2011 - piksel 32m</Title>
+   <Abstract>Fotoplan z 2011 roku z pikselem 32m dla zakresu skal od nieskończoności do 1:120000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #29 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2011_4m</Name>
+   <Title>Raster - Fotoplan 2011 - piksel 4m</Title>
+   <Abstract>Fotoplan z 2011 roku z pikselem 4m dla zakresu skal od 1:30000 do 1:15000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #30 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2011_8m</Name>
+   <Title>Raster - Fotoplan 2011 - piksel 8m</Title>
+   <Abstract>Fotoplan z 2011 roku z pikselem 8m dla zakresu skal od 1:60000 do 1:30000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #31 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/OpiekaZdrowotna_poradnie_zdrowia_psychicznego</Name>
+   <Title>Opieka Zdrowotna - Poradnie Zdrowia Psychicznego</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #32 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/OpiekaZdrowotna_poradnie_psych_pedagogiczne</Name>
+   <Title>Opieka Zdrowotna - Poradnie Psychologiczno-Pedagogiczne</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #33 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/OpiekaSpoleczna_zlobki</Name>
+   <Title>Opieka Społeczna - złobki i kluby dziecięce</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #34 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/OpiekaZdrowotna_Szpitale</Name>
+   <Title>Opieka zdrowotna - Szpitale</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #35 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_budynki do zachowania</Name>
+   <Title>Plany zagospodarowania - budynki do zachowania</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #36 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_budynki_wpisane_do_rejestru_zabytkow</Name>
+   <Title>Plany zagospodarowania - budynki wpisane do rejestru zabytków</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #37 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_ciagi_piesze</Name>
+   <Title>Plany zagospodarowania - ciągi piesze</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #38 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_dominanta_wysokosciowa</Name>
+   <Title>Plany zagospodarowania - dominanty wysokościowe</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #39 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_dominanty_przestrzenne</Name>
+   <Title>Plany zagospodarowania - dominanty przestrzenne</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #40 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_granice_obszarow_objetych_ochrona_konserwatorska</Name>
+   <Title>Plany zagospodarowania - granice obszarów objętych ochroną konserwatorską</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #41 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_granice_obszarow_objetych_ochrona_srodowiska</Name>
+   <Title>Plany zagospodarowania - granice obszarów objętych ochroną środowiska</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #42 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_granice_obszaru_objetego_planem</Name>
+   <Title>Plany zagospodarowania - granice obszaru objętego planem</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #43 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_metro</Name>
+   <Title>Plany zagospodarowania - metro</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #44 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_napowietrzne_linie_EE</Name>
+   <Title>Plany zagospodarowania - napowietrzne linie EE</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #45 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_nieprzekraczalna_granica_pochowkow</Name>
+   <Title>Plany zagospodarowania - nieprzekraczalne granice pochówków</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #46 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_nieprzekraczalna_linia_zabudowy_podziemii</Name>
+   <Title>Plany zagospodarowania - nieprzekraczalne linie zabudowy podziemii</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #47 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_nieprzekraczalna_linia_zabudowy_przewieszen</Name>
+   <Title>Plany zagospodarowania - nieprzekraczalne linie zabudowy przewieszeń</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #48 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_nieprzekraczalna_linia_zabudowy_zwyzki</Name>
+   <Title>Plany zagospodarowania - nieprzekraczalne linie zabudowy zwyżki</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #49 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_nieprzekraczalne_linie_zabudowy</Name>
+   <Title>Plany zagospodarowania - nieprzekraczalne linie zabudowy</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #50 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_obiekty_wpisane_do_rejestru_zabytkow</Name>
+   <Title>Plany zagospodarowania - obiekty wpisane do rejestru zabytków</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #51 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_obowiazujace_linie_zabudowy</Name>
+   <Title>Plany zagospodarowania - obowiązujące linie zabudowy</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #52 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_osie_kompozycyjne</Name>
+   <Title>Plany zagospodarowania - osie kompozycyjne</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #53 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_osie_widokowe</Name>
+   <Title>Plany zagospodarowania - osie widokowe</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #54 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_parkingi_na_poziomie_terenu</Name>
+   <Title>Plany zagospodarowania - parkingi na poziomie terenu</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #55 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_parkingi_podziemne</Name>
+   <Title>Plany zagospodarowania - parkingi podziemne</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #56 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_parkingi_zatokowe</Name>
+   <Title>Plany zagospodarowania - parkingi zatokowe</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #57 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_place_miejskie</Name>
+   <Title>Plany zagospodarowania - place miejskie</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #58 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_pomnik_przyrody_nieozywionej</Name>
+   <Title>Plany zagospodarowania - pomniki przyrody nieożywionej</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #59 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_pomniki</Name>
+   <Title>Plany zagospodarowania - pomniki</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #60 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_pomniki_przyrody</Name>
+   <Title>Plany zagospodarowania - pomniki przyrody</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #61 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_sciezki_rowerowe</Name>
+   <Title>Plany zagospodarowania - ścieżki rowerowe</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #62 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_strefy_archeologiczne</Name>
+   <Title>Plany zagospodarowania - strefy archeologiczne</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #63 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_strefy_ograniczen</Name>
+   <Title>Plany zagospodarowania - strefy ograniczeń</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #64 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_tereny_o_roznych-zasadach_zagospodarowania</Name>
+   <Title>Plany zagospodarowania - tereny o różnych zasadach zagospodarowania</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #65 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_tereny_zamkniete</Name>
+   <Title>Plany zagospodarowania - tereny zamknięte</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #66 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Ramka_Zasadnicza_0250</Name>
+   <Title>Geodezja - Sekcje ZMM 1:250</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #67 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Ramka_Zasadnicza_0500</Name>
+   <Title>Geodezja - Sekcje ZMM 1:500</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #68 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Ramka_Zasadnicza_1000</Name>
+   <Title>Geodezja - Sekcje ZMM 1:1000</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #69 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Ramka_Zasadnicza_2000</Name>
+   <Title>Geodezja - Sekcje ZMM 1:2000</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #70 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_orto2010_8m</Name>
+   <Title>Raster - Ortofotomapa 2010 - piksel 8m</Title>
+   <Abstract>Ortofotomapa z 2010 roku z pikselem 8m dla zakresu skal od 1:60000 do 1:30000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #71 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_orto2010_4m</Name>
+   <Title>Raster - Ortofotomapa 2010 - piksel 4m</Title>
+   <Abstract>Ortofotomapa z 2010 roku z pikselem 4m dla zakresu skal od 1:30000 do 1:15000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #72 -->
+  <Layer queryable="1" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_orto2010_32m</Name>
+   <Title>Raster - Ortofotomapa 2010 - piksel 32m</Title>
+   <Abstract>Ortofotomapa z 2010 roku z pikselem 32m dla zakresu skal od nieskończoności do 1:120000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #73 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_orto2010_16m</Name>
+   <Title>Raster - Ortofotomapa 2010 - piksel 16m</Title>
+   <Abstract>Ortofotomapa z 2010 roku z pikselem 16m dla zakresu skal od 1:120000 do 1:60000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #74 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_orto2010_10cm</Name>
+   <Title>Raster - Ortofotomapa 2010 - piksel 10 cm</Title>
+   <Abstract>Ortofotomapa z 2010 roku z pikselem 10cm dla zakresu skal od 0 do 1:15000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #75 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_orto1945</Name>
+   <Title>Raster - Ortofoto 1945</Title>
+   <Abstract>Ortofotomapa zniszczonej Warszawy z roku 1945</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #76 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2012_32m</Name>
+   <Title>Raster - Fotoplan 2012 - piksel 32m</Title>
+   <Abstract>Fotoplan z 2012 roku z pikselem 32m dla zakresu skal od nieskończoności do 1:120000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #77 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2012_4m</Name>
+   <Title>Raster - Fotoplan 2012 - piksel 4m</Title>
+   <Abstract>Fotoplan z 2012 roku z pikselem 4m dla zakresu skal od 1:30000 do 1:15000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #78 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/studium_uwarunkowan</Name>
+   <Title>Raster - Studium uwarunkowań</Title>
+   <Abstract>Studium uwarunkowań i kierunków zagospodarowania przestrzennego, dostępne w skalach od 1:256 000 do 1:8 000.</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #79 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Zagrozenia_waly_ppow</Name>
+   <Title>Zagrożenia - Wały przeciwpowodziowe</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #80 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="1">
+   <Name>WMS/serwisy_ibombo_samoobs</Name>
+   <Title>Rowery-Serwisy_ibombo_samooblugowe</Title>
+   <Abstract>Rowerowe serwisy samoobsługowe Ibombo</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #81 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="1">
+   <Name>WMS/serwisy_rowerowe</Name>
+   <Title>Rowery-srwisy_rowerowe</Title>
+   <Abstract>Serwisy rowerowe</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #82 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Komunikacja_msi_granica_1_strefy_taxi</Name>
+   <Title>Komunikacja - Granica 1. Strefy TAXI</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #83 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2015_16m</Name>
+   <Title>Raster - Fotoplan 2015 - piksel 16m</Title>
+   <Abstract>Fotoplan z 2015 roku z pikselem 16m dla zakresu skal od 1:120000 do 1:60000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #84 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2015_32m</Name>
+   <Title>Raster - Fotoplan 2015 - piksel 32m</Title>
+   <Abstract>Fotoplan z 2015 roku z pikselem 32m dla zakresu skal od nieskończoności do 1:120000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #85 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2015_4m</Name>
+   <Title>Raster - Fotoplan 2015 - piksel 4m</Title>
+   <Abstract>Fotoplan z 2015 roku z pikselem 4m dla zakresu skal od 1:30000 do 1:15000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #86 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2015_8m</Name>
+   <Title>Raster - Fotoplan 2015 - piksel 8m</Title>
+   <Abstract>Fotoplan z 2015 roku z pikselem 8m dla zakresu skal od 1:60000 do 1:30000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #87 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2014_10cm</Name>
+   <Title>Raster - Fotoplan 2014 - piksel 10cm</Title>
+   <Abstract>Fotoplan z 2014 roku z pikselem 10cm dla zakresu skal od 0 do 1:15000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #88 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2014_16m</Name>
+   <Title>Raster - Fotoplan 2014 - piksel 16m</Title>
+   <Abstract>Fotoplan z 2014 roku z pikselem 16m dla zakresu skal od 1:120000 do 1:60000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #89 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2014_32m</Name>
+   <Title>Raster - Fotoplan 2014 - piksel 32m</Title>
+   <Abstract>Fotoplan z 2014 roku z pikselem 32m dla zakresu skal od nieskończoności do 1:120000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #90 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2014_4m</Name>
+   <Title>Raster - Fotoplan 2014 - piksel 4m</Title>
+   <Abstract>Fotoplan z 2014 roku z pikselem 4m dla zakresu skal od 1:30000 do 1:15000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #91 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2014_8m</Name>
+   <Title>Raster - Fotoplan 2014 - piksel 8m</Title>
+   <Abstract>Fotoplan z 2014 roku z pikselem 8m dla zakresu skal od 1:60000 do 1:30000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #92 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2015_10cm</Name>
+   <Title>Raster - Fotoplan 2015 - piksel 10cm</Title>
+   <Abstract>Fotoplan z 2015 roku z pikselem 10cm dla zakresu skal od 0 do 1:15000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #93 -->
+  <Layer queryable="1" cascaded="0" noSubsets="0" opaque="1">
+   <Name>WMS/ENOM_Place_Skwery</Name>
+   <Title>ENOM_Place_Skwery</Title>
+   <Abstract>Obiekty liniowe nazewnictwa m.st. Warszawy</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #94 -->
+  <Layer queryable="1" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/ENOM_Punkty_Adresowe</Name>
+   <Title>ENOM_Punkty_Adresowe</Title>
+   <Abstract>Punkty Adresowe m.st Warszawy</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #95 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2016_32m</Name>
+   <Title>Raster - Fotoplan 2016 - piksel 32m</Title>
+   <Abstract>Fotoplan z 2016 roku z pikselem 32m dla zakresu skal od nieskończoności do 1:120000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #96 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2016_4m</Name>
+   <Title>Raster - Fotoplan 2016 - piksel 4m</Title>
+   <Abstract>Fotoplan z 2016 roku z pikselem 4m dla zakresu skal od 1:30000 do 1:15000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #97 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2016_8m</Name>
+   <Title>Raster - Fotoplan 2016 - piksel 8m</Title>
+   <Abstract>Fotoplan z 2016 roku z pikselem 8m dla zakresu skal od 1:60000 do 1:30000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #98 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Baza_noclegowa_Akademiki</Name>
+   <Title>Baza noclegowa - Akademiki</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #99 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Baza_noclegowa_Apartamenty</Name>
+   <Title>Baza noclegowa - Apartamenty</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #100 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Zielen_Grupy_krzewow</Name>
+   <Title>Zieleń - Grupy krzewów</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #101 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Zielen_Zywoploty</Name>
+   <Title>Zieleń - Żywopłoty</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #102 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Zielen_Pomniki_przyrody</Name>
+   <Title>Zieleń - Pomniki przyrody</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #103 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Zielen_Kwietniki</Name>
+   <Title>Zieleń - Kwietniki</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #104 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Zielen_Pnacza</Name>
+   <Title>Zieleń - Pnącza</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #105 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Zielen_Trawniki</Name>
+   <Title>Zieleń - Trawniki</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #106 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Administracja_Ambasady</Name>
+   <Title>Administracja - Ambasady</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #107 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Koryto_wisly</Name>
+   <Title>Raster - Koryto Wisły</Title>
+   <Abstract>Ortofotomapa z pikselem 5 cm dla koryta Wisły wykonana w roku 2015.</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #108 -->
+  <Layer queryable="1" cascaded="0" noSubsets="0" opaque="1">
+   <Name>WMS/Arch_Decyzje_warunki_zabudowy</Name>
+   <Title>Decyzje o warunkach zabudowy</Title>
+   <Abstract>Warstwa wydanych decyzji o warunkach zabudowy od sakli 1:40000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #109 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="1">
+   <Name>WMS/Raster_plan_39</Name>
+   <Title>Raster - Plan 1939</Title>
+   <Abstract>Plan Warszawy z 1939 r. widoczny w zakresie skal 1:250 - 1:50000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.000" miny="51.00" maxx="22.000" maxy="53.00"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7400000.00" miny="5700000.00" maxx="7600000.00" maxy="5900000.00"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.000" miny="51.00" maxx="22.000" maxy="53.00"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #110 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Administracja_Biura_Urzedu</Name>
+   <Title>Administracja - Biura Urzędu Miasta</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #111 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Administracja_Konsulaty</Name>
+   <Title>Administracja - Konsulaty</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #112 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Administracja_Sady</Name>
+   <Title>Administracja - Sądy</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #113 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Administracja_Urzedy_Dzielnic</Name>
+   <Title>Administracja - Urzędy dzielnic</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #114 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Administracja_Urzedy_Skarbowe</Name>
+   <Title>Administracja - Urzędy Skarbowe</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #115 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Administracja_USC</Name>
+   <Title>Administracja - USC</Title>
+   <Abstract>Urzędy Stanu Cywilnego</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #116 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Administracja_ZUS</Name>
+   <Title>Administracja - Placówki ZUS</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #117 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Baza_noclegowa_Campingi</Name>
+   <Title>Baza noclegowa - Campingi</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #118 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Baza_noclegowa_Hotele</Name>
+   <Title>Baza noclegowa - Hotele</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #119 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Baza_noclegowa_Schroniska</Name>
+   <Title>Baza noclegowa - Schroniska</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #120 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Bezpieczenstwo_Policja</Name>
+   <Title>Bezpieczeństwo - Posterunki Policji</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #121 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Bezpieczenstwo_PSP</Name>
+   <Title>Bezpieczeństwo - Jednostki Straży Pożarnej</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #122 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Cmentarze_groby</Name>
+   <Title>Religia - Cmentarze - Groby</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #123 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Cmentarze_POI</Name>
+   <Title>Religia - Cmentarzei - Ważne miejsca</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #124 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Cmentarze_zasiegi</Name>
+   <Title>Religia - Cmentarze</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #125 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Edukacja_Gimnazja</Name>
+   <Title>Edukacja - Gimnazja</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #126 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Edukacja_Licea</Name>
+   <Title>Edukacja - Licea</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #127 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Edukacja_Przedszkola</Name>
+   <Title>Edukacja - Przedszkola</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #128 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Edukacja_SzkolyPodstawowe</Name>
+   <Title>Edukacja - Szkoły Podstawowe</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #129 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Edukacja_SzkolyPodstawoweObwody</Name>
+   <Title>Edukacja - Obwody Szkół Podstawowych</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #130 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Edukacja_SzkolyPolicealne</Name>
+   <Title>Edukacja - Szkoły Policealne</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #131 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Edukacja_Technika</Name>
+   <Title>Edukacja - Technika</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #132 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Edukacja_WyzszeUczelnie</Name>
+   <Title>Edukacja - Uczelnie Wyższe</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #133 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Geodezja_Obszary_msi</Name>
+   <Title>Geodezja - Obszary MSI</Title>
+   <Abstract>Obszary Miejskiejgo Systemu Informacji</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #134 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Historia_granica_1916</Name>
+   <Title>Historia - Granica Warszawy 1916</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #135 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Historia_granica_1938</Name>
+   <Title>Historia - Granica Warszawy 1938</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #136 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Historia_granica_1930</Name>
+   <Title>Historia - Granica Warszawy 1930</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #137 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Historia_granica_1951</Name>
+   <Title>Historia - Granica Warszawy 1951</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #138 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Historia_granica_1957</Name>
+   <Title>Historia - Granica Warszawy 1957</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #139 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Historia_granica_1978</Name>
+   <Title>Historia - Granica Warszawy 1978</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #140 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="1">
+   <Name>WMS/Historia_ulice_1939_liniowe</Name>
+   <Title>Historia - Ulice istniejące w 1939 roku</Title>
+   <Abstract>Ulice istniejące w 1939 roku widoczne w skalach 1:250 - 1:32000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.000" miny="51.00" maxx="22.000" maxy="53.00"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7400000.00" miny="5700000.00" maxx="7600000.00" maxy="5900000.00"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.000" miny="51.00" maxx="22.000" maxy="53.00"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #141 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Historia_ulice_1939_glowne</Name>
+   <Title>Historia - Ulice główne istniejące w 1939 roku</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #142 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="1">
+   <Name>WMS/Historia_ulice_1939_powierzchniowe</Name>
+   <Title>Historia - Place istniejące w 1939 roku</Title>
+   <Abstract>Nazwy placów w 1939 roku widoczny w skalach 1:250 - 1:8000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.000" miny="51.00" maxx="22.000" maxy="53.00"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7400000.00" miny="5700000.00" maxx="7600000.00" maxy="5900000.00"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.000" miny="51.00" maxx="22.000" maxy="53.00"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #143 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Inne_Strefa_Z2</Name>
+   <Title>Inne - Strefa ograniczeń przeznaczenia</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #144 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Komunikacja_DworceKolejowe</Name>
+   <Title>Komunikacja - Dworce kolejowe</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #145 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Komunikacja_Parkingi_P_R</Name>
+   <Title>Komunikacja - Parkingi P+R</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #146 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Komunikacja_PrzystankiKM(PKP)</Name>
+   <Title>Komunikacja - Przystanki KM (PKP)</Title>
+   <Abstract>Przystanki Kolei Mazowieckich (PKP)</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #147 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Ramka_Sekcje_2000</Name>
+   <Title>Geodezja - Ramka Ortofoto Sekcje 1:2000</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #148 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto1935</Name>
+   <Title>Raster - Fotoplan z 1935 roku</Title>
+   <Abstract>Fotoplan z 1935 roku</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #149 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2012_16m</Name>
+   <Title>Raster - Fotoplan 2012 - piksel 16m</Title>
+   <Abstract>Fotoplan z 2012 roku z pikselem 16m dla zakresu skal od 1:120000 do 1:60000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #150 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Religia_koscioly_kaplice</Name>
+   <Title>Religia - Kościoły i kaplice</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #151 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Bieżnia</Name>
+   <Title>Sport - Bieżnie</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #152 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Fitness</Name>
+   <Title>Sport - Kluby Fitness</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #153 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Hala_sportowa</Name>
+   <Title>Sport - Hale Sportowe</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #154 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Inne</Name>
+   <Title>Sport - Inne obiekty</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #155 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Korty_tenisowe</Name>
+   <Title>Sport - Korty Tenisowe</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #156 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Koszykowka</Name>
+   <Title>Sport - Boiska do koszykówki</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #157 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Kregielnie</Name>
+   <Title>Sport - Kręgielnie</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #158 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Lodowiska</Name>
+   <Title>Sport - Lodowiska</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #159 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Pchnięcie_kulą</Name>
+   <Title>Sport - Boiska do pchnięcia kulą</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #160 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Pilka_nozna_1</Name>
+   <Title>Sport - Boiska do piłki nożnej</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #161 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Pilka_reczna</Name>
+   <Title>Sport - Boiska do piłki ręcznej</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #162 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Plywalnie</Name>
+   <Title>Sport - Pływalnie kryte</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #163 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Plywalnie_odkryte</Name>
+   <Title>Sport - Pływalnie odkryte</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #164 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Sale_gimnastyczne</Name>
+   <Title>Sport - Sale gimnastyczne</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #165 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Sale_i_pawilony_spec</Name>
+   <Title>Sport - Sale i pawilony specjalistyczne</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #166 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Scianka_wspinaczkowa</Name>
+   <Title>Sport - Ścianki wspinaczkowe</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #167 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Siatkowka</Name>
+   <Title>Sport - Boiska do siatkówki</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #168 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Silownie</Name>
+   <Title>Sport - Siłownie</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #169 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Skatepark</Name>
+   <Title>Sport - Skateparki</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #170 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Skok_w_dal</Name>
+   <Title>Sport - Boiska do skoku w dal</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #171 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Skok_wzwyż</Name>
+   <Title>Sport - Boiska do skoku wzwyż</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #172 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Sporty_lodziowe</Name>
+   <Title>Sport - Sporty łodziowe</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #173 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Squash</Name>
+   <Title>Sport - Boiska do squasha</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #174 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Stadiony_LA</Name>
+   <Title>Sport - Stadiony lekkoatletyczne</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #175 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Strzelnice</Name>
+   <Title>Sport - Strzelnice</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #176 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Sport_Tory</Name>
+   <Title>Sport - Tory</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #177 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Turystyka_punkty_informacyjne_msi</Name>
+   <Title>Turystyka - Punkty Informacyjne Miejskiego Systemu Informacji</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #178 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Turystyka_Punkty_IT</Name>
+   <Title>Turystyka - Punkty Informacji Turystycznej</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #179 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Zielen_Krzewy</Name>
+   <Title>Zieleń - Krzewy</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #180 -->
+  <Layer queryable="1" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Geodezja_Dzialki</Name>
+   <Title>Geodezja_Dzialki</Title>
+   <Abstract>Warstwa z granicami działek ewidencyjnych z pzgik prowadzonego przez m.st. Warszawa. Wykorzystanie danych zgodnie z Ustawą Prawo Geodezyjne i Kartograficzne. Dane są widoczne w kalach większych niz 1:4000</Abstract>
+   
+   <KeywordList>
+     <Keyword>EGIB</Keyword>
+ <Keyword> działki</Keyword>
+ <Keyword> ewidencja</Keyword>
+ 
+   </KeywordList>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.852" miny="52.098" maxx="21.272" maxy="52.368"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7489860.710" miny="5773789.510" maxx="7518549.170" maxy="5803861.960"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="626822.239" miny="471799.425" maxx="654659.339" maxy="502640.357"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.852" miny="52.098" maxx="21.272" maxy="52.368"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #181 -->
+  <Layer queryable="1" cascaded="0" noSubsets="0" opaque="1">
+   <Name>WMS/Arch_Dcyzje_pozwolenia_na_budowe</Name>
+   <Title>Decyzje o pozwoleniu na budowę</Title>
+   <Abstract>Warstwa wydanych decyzji o pozwoleniu na budowę od skali 1:40000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #182 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Zielen_Drzewa</Name>
+   <Title>Zieleń - Drzewa</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #183 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Zielen_Grupy_drzew</Name>
+   <Title>Zieleń - Grupy drzew</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.851603" miny="52.097603" maxx="21.267225" maxy="52.366737"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #184 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/UP_cieplownicza</Name>
+   <Title>UP-ciepłownicza</Title>
+   <Abstract>Sieć ciepłownicza - od skali 1:2000. Dane z ODGiK m.st. Warszawy</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7400000.00" miny="5700000.00" maxx="7600000.00" maxy="5900000.00"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #185 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/UP_elektroenergetyczna</Name>
+   <Title>UP-elektroenergetyczna</Title>
+   <Abstract>Sieć elektroenergetyczna - od skali 1:2000. Dane z ODGiK m.st. Warszawy</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7400000.00" miny="5700000.00" maxx="7600000.00" maxy="5900000.00"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #186 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/UP_elem_naziemne</Name>
+   <Title>UP-elementy naziemne</Title>
+   <Abstract>Elementy naziemne urządzen poedziemnych - od skali 1:2000. Dane z ODGiK m.st. Warszawy</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7400000.00" miny="5700000.00" maxx="7600000.00" maxy="5900000.00"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #187 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/UP_gazowa</Name>
+   <Title>UP-gazowa</Title>
+   <Abstract>Sieć gazowa - od skali 1:2000. Dane z ODGiK m.st. Warszawy</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7400000.00" miny="5700000.00" maxx="7600000.00" maxy="5900000.00"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #188 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/UP_kanalizacyjna</Name>
+   <Title>UP-kanalizacyjna</Title>
+   <Abstract>Sieć kanalizacyjna - od skali 1:2000. Dane z ODGiK m.st. Warszawy</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7400000.00" miny="5700000.00" maxx="7600000.00" maxy="5900000.00"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #189 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/UP_projekty_ZUD</Name>
+   <Title>UP-projekty-ZUD</Title>
+   <Abstract>Projekty ZUD - od skali 1:2000. Dane z ODGiK m.st. Warszawy</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7400000.00" miny="5700000.00" maxx="7600000.00" maxy="5900000.00"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #190 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/UP_specjalna</Name>
+   <Title>UP-specjalna</Title>
+   <Abstract>Sieć specjalna - od skali 1:2000. Dane z ODGiK m.st. Warszawy</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7400000.00" miny="5700000.00" maxx="7600000.00" maxy="5900000.00"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #191 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/UP_telekomunikacyjna</Name>
+   <Title>UP-telekomunikacyjna</Title>
+   <Abstract>Sieć telekomunikacyjna - od skali 1:2000. Dane z ODGiK m.st. Warszawy</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7400000.00" miny="5700000.00" maxx="7600000.00" maxy="5900000.00"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #192 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/UP_wodociagowa</Name>
+   <Title>UP-wodociągowa</Title>
+   <Abstract>Sieć wodociągowa - od skali 1:2000. Dane z ODGiK m.st. Warszawy</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7400000.00" miny="5700000.00" maxx="7600000.00" maxy="5900000.00"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #193 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Edukacja_SzkolyBranzowe</Name>
+   <Title>Edukacja - Szkoły branżowe</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.000" miny="51.00" maxx="22.000" maxy="53.00"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7400000.00" miny="5700000.00" maxx="7600000.00" maxy="5900000.00"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.000" miny="51.00" maxx="22.000" maxy="53.00"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #194 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Religia_parafie_rzymsko_katolickie</Name>
+   <Title>Religia - Parafie rzymskokatolickie</Title>
+   <Abstract>Parafie rzymskokatolickie</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #195 -->
+  <Layer queryable="1" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Geodezja_Granice_Dzielnic</Name>
+   <Title>Geodezja - Granice dzielnic</Title>
+   <Abstract>Granice dzielnic</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #196 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2016_10cm</Name>
+   <Title>Raster - Fotoplan 2016 - piksel 10cm</Title>
+   <Abstract>Fotoplan z 2016 roku z pikselem 10cm dla zakresu skal od 0 do 1:15000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #197 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2016_16m</Name>
+   <Title>Raster - Fotoplan 2016 - piksel 16m</Title>
+   <Abstract>Fotoplan z 2016 roku z pikselem 16m dla zakresu skal od 1:120000 do 1:60000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #198 -->
+  <Layer queryable="1" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/ENOM_Ulice</Name>
+   <Title>ENOM_Ulice</Title>
+   <Abstract>Obiekty liniowe nazewnictwa m.st. Warszawy</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.82" miny="52.05" maxx="21.32" maxy="52.40"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #199 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_linie rozgraniczajace</Name>
+   <Title>Plany zagospodarowania - linie rozgraniczające</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #200 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Plany_plany_zasiegi</Name>
+   <Title>Plany zagospodarowania - zasięgi planów</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #201 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Raster_foto2017_8cm</Name>
+   <Title>Raster - Fotoplan 2017 - piksel 8cm</Title>
+   <Abstract>Fotoplan z 2017 roku z pikselem 8cm dla zakresu skal od 0 do 1:30000</Abstract>
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+    <LatLonBoundingBox minx="20.837" miny="52.091" maxx="21.282" maxy="52.378"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488800.000" miny="5773000.000" maxx="7519200.000" maxy="5805000.000"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="625784.121" miny="470981.352" maxx="655278.249" maxy="503795.573"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.837" miny="52.091" maxx="21.282" maxy="52.378"/>
+ 
+   
+  </Layer>
+ 
+  <!-- Published Layer #202 -->
+  <Layer queryable="0" cascaded="0" noSubsets="0" opaque="0">
+   <Name>WMS/Rowery_trasy_rowerowe</Name>
+   <Title>Rowery-Trasy rowerowe</Title>
+   
+   
+   
+    
+  <SRS>EPSG:2178</SRS>
+ 
+  <SRS>EPSG:4326</SRS>
+ 
+  <SRS>EPSG:2180</SRS>
+ 
+    <LatLonBoundingBox minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+    
+  <BoundingBox SRS="EPSG:2178" minx="7488477.25192" miny="5772296.739585" maxx="7519616.26268" maxy="5805199.299715"/>
+ 
+  <BoundingBox SRS="EPSG:4326" minx="20.8721" miny="52.0838" maxx="21.2475" maxy="52.3803"/>
+ 
+  <BoundingBox SRS="EPSG:2180" minx="619971.000" miny="469226.00" maxx="661090.00" maxy="505550.00"/>
+ 
+   
+  </Layer>
+ 
+    </Layer>
+   </Capability>
+  </WMT_MS_Capabilities>
+ 
Index: /trunk/test/unit/org/openstreetmap/josm/TestUtils.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/TestUtils.java	(revision 13732)
+++ /trunk/test/unit/org/openstreetmap/josm/TestUtils.java	(revision 13733)
@@ -15,4 +15,8 @@
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.time.Instant;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.Temporal;
 import java.util.Arrays;
 import java.util.Collection;
@@ -38,4 +42,7 @@
 import org.openstreetmap.josm.tools.JosmRuntimeException;
 import org.openstreetmap.josm.tools.Utils;
+
+import com.github.tomakehurst.wiremock.WireMockServer;
+import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
@@ -380,3 +387,46 @@
         }
     }
+
+    /**
+     * Return WireMock server serving files under ticker directory
+     * @param ticketId Ticket numeric identifier
+     * @return WireMock HTTP server on dynamic port
+     */
+    public static WireMockServer getWireMockServer(int ticketId) {
+            return new WireMockServer(
+                    WireMockConfiguration.options()
+                        .dynamicPort()
+                        .usingFilesUnderDirectory(getRegressionDataDir(ticketId))
+                    );
+    }
+
+    /**
+     * Return WireMock server serving files under ticker directory
+     * @return WireMock HTTP server on dynamic port
+     */
+    public static WireMockServer getWireMockServer() {
+            return new WireMockServer(
+                    WireMockConfiguration.options()
+                        .dynamicPort()
+                    );
+    }
+    /**
+     * Renders Temporal to RFC 1123 Date Time
+     * @param time
+     * @return string representation according to RFC1123 of time
+     */
+    public static String getHTTPDate(Temporal time) {
+        return DateTimeFormatter.RFC_1123_DATE_TIME.withZone(ZoneOffset.UTC).format(time);
+    }
+
+    /**
+     * Renders java time stamp to RFC 1123 Date Time
+     * @param time
+     * @return string representation according to RFC1123 of time
+     */
+    public static String getHTTPDate(long time) {
+        return getHTTPDate(Instant.ofEpochMilli(time));
+    }
+
+
 }
Index: /trunk/test/unit/org/openstreetmap/josm/actions/AddImageryLayerActionTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/actions/AddImageryLayerActionTest.java	(revision 13732)
+++ /trunk/test/unit/org/openstreetmap/josm/actions/AddImageryLayerActionTest.java	(revision 13733)
@@ -70,9 +70,16 @@
     @Test
     public void testActionPerformedEnabledWms() {
-        wireMockRule.stubFor(get(urlEqualTo("/wms?VERSION=1.1.1&SERVICE=WMS&REQUEST=GetCapabilities"))
+        wireMockRule.stubFor(get(urlEqualTo("/wms?SERVICE=WMS&REQUEST=GetCapabilities&VERSION=1.1.1"))
                 .willReturn(aResponse()
-                    .withStatus(200)
-                    .withHeader("Content-Type", "text/xml")
-                    .withBodyFile("imagery/wms-capabilities.xml")));
+                        .withStatus(200)
+                        .withHeader("Content-Type", "text/xml")
+                        .withBodyFile("imagery/wms-capabilities.xml")));
+        wireMockRule.stubFor(get(urlEqualTo("/wms?SERVICE=WMS&REQUEST=GetCapabilities"))
+                .willReturn(aResponse()
+                        .withStatus(404)));
+        wireMockRule.stubFor(get(urlEqualTo("/wms?SERVICE=WMS&REQUEST=GetCapabilities&VERSION=1.3.0"))
+                .willReturn(aResponse()
+                        .withStatus(404)));
+
         new AddImageryLayerAction(new ImageryInfo("localhost", "http://localhost:" + wireMockRule.port() + "/wms?",
                 "wms_endpoint", null, null)).actionPerformed(null);
Index: /trunk/test/unit/org/openstreetmap/josm/data/cache/HostLimitQueueTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/data/cache/HostLimitQueueTest.java	(revision 13732)
+++ /trunk/test/unit/org/openstreetmap/josm/data/cache/HostLimitQueueTest.java	(revision 13733)
@@ -14,4 +14,5 @@
 import org.junit.Rule;
 import org.junit.Test;
+import org.openstreetmap.josm.data.imagery.TileJobOptions;
 import org.openstreetmap.josm.testutils.JOSMTestRules;
 import org.openstreetmap.josm.tools.Logging;
@@ -54,5 +55,5 @@
 
         Task(ICacheAccess<String, CacheEntry> cache, URL url, AtomicInteger counter) {
-            super(cache, 1, 1, null);
+            super(cache, new TileJobOptions(1, 1, null, 10));
             this.url = url;
             this.counter = counter;
Index: /trunk/test/unit/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJobTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJobTest.java	(revision 13732)
+++ /trunk/test/unit/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJobTest.java	(revision 13733)
@@ -2,6 +2,8 @@
 package org.openstreetmap.josm.data.cache;
 
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
@@ -9,12 +11,21 @@
 import java.net.URL;
 import java.nio.charset.StandardCharsets;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.commons.jcs.access.behavior.ICacheAccess;
+import org.apache.commons.jcs.engine.behavior.ICacheElement;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
+import org.openstreetmap.josm.TestUtils;
 import org.openstreetmap.josm.data.cache.ICachedLoaderListener.LoadResult;
+import org.openstreetmap.josm.data.imagery.TileJobOptions;
 import org.openstreetmap.josm.testutils.JOSMTestRules;
 import org.openstreetmap.josm.tools.Logging;
+
+import com.github.tomakehurst.wiremock.client.WireMock;
+import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
+import com.github.tomakehurst.wiremock.junit.WireMockRule;
+import com.github.tomakehurst.wiremock.matching.UrlPattern;
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
@@ -25,14 +36,26 @@
 public class JCSCachedTileLoaderJobTest {
 
+    /**
+     * mocked tile server
+     */
+    @Rule
+    public WireMockRule tileServer = new WireMockRule(WireMockConfiguration.options()
+            .dynamicPort());
+
     private static class TestCachedTileLoaderJob extends JCSCachedTileLoaderJob<String, CacheEntry> {
         private String url;
         private String key;
 
-        TestCachedTileLoaderJob(String url, String key) throws IOException {
-            super(getCache(), 30000, 30000, null);
+        TestCachedTileLoaderJob(String url, String key)  {
+            this(url, key, (int) TimeUnit.DAYS.toSeconds(1));
+        }
+
+        TestCachedTileLoaderJob(String url, String key, int minimumExpiry)  {
+            super(getCache(), new TileJobOptions(30000, 30000, null, minimumExpiry));
 
             this.url = url;
             this.key = key;
         }
+
 
         @Override
@@ -52,5 +75,5 @@
         @Override
         protected CacheEntry createCacheEntry(byte[] content) {
-            return new CacheEntry("dummy".getBytes(StandardCharsets.UTF_8));
+            return new CacheEntry(content);
         }
     }
@@ -60,4 +83,5 @@
         private boolean ready;
         private LoadResult result;
+        private byte[] data;
 
         @Override
@@ -66,4 +90,7 @@
             this.ready = true;
             this.result = result;
+            if (data != null) {
+                this.data = data.content;
+            }
             this.notifyAll();
         }
@@ -113,16 +140,5 @@
         String key = "key_unknown_host";
         TestCachedTileLoaderJob job = new TestCachedTileLoaderJob("http://unkownhost.unkownhost/unkown", key);
-        Listener listener = new Listener();
-        job.submit(listener, true);
-        synchronized (listener) {
-            while (!listener.ready) {
-                try {
-                    listener.wait();
-                } catch (InterruptedException e1) {
-                    // do nothing, still wait
-                    Logging.trace(e1);
-                }
-            }
-        }
+        Listener listener = submitJob(job);
         assertEquals(LoadResult.FAILURE, listener.result); // because response will be cached, and that is checked below
         assertEquals("java.net.UnknownHostException: unkownhost.unkownhost", listener.attributes.getErrorMessage());
@@ -135,38 +151,328 @@
 
         job = new TestCachedTileLoaderJob("http://unkownhost.unkownhost/unkown", key);
-        listener = new Listener();
-        job.submit(listener, true);
+        listener = submitJob(job);
+        assertEquals(LoadResult.SUCCESS, listener.result);
+        assertFalse(job.isCacheElementValid());
+    }
+
+    private void doTestStatusCode(int responseCode) throws IOException {
+        TestCachedTileLoaderJob job = getStatusLoaderJob(responseCode);
+        Listener listener = submitJob(job);
+        assertEquals(responseCode, listener.attributes.getResponseCode());
+    }
+
+    private Listener submitJob(TestCachedTileLoaderJob job) throws IOException {
+        return submitJob(job, true);
+    }
+
+    private Listener submitJob(TestCachedTileLoaderJob job, boolean force) throws IOException {
+        Listener listener = new Listener();
+        job.submit(listener, force);
         synchronized (listener) {
             while (!listener.ready) {
                 try {
                     listener.wait();
-                } catch (InterruptedException e1) {
+                } catch (InterruptedException e) {
                     // do nothing, wait
-                    Logging.trace(e1);
+                    Logging.trace(e);
                 }
             }
         }
-        assertEquals(LoadResult.SUCCESS, listener.result);
-        assertFalse(job.isCacheElementValid());
-    }
-
-    @SuppressFBWarnings(value = "WA_NOT_IN_LOOP")
-    private void doTestStatusCode(int responseCode) throws IOException, InterruptedException {
-        TestCachedTileLoaderJob job = getStatusLoaderJob(responseCode);
-        Listener listener = new Listener();
-        job.submit(listener, true);
-        synchronized (listener) {
-            if (!listener.ready) {
-                listener.wait();
-            }
-        }
-        assertEquals(responseCode, listener.attributes.getResponseCode());
-    }
-
-    private static TestCachedTileLoaderJob getStatusLoaderJob(int responseCode) throws IOException {
+        return listener;
+    }
+
+    /**
+     * That no requst is made when entry is in cache and force == false
+     * @throws IOException
+     */
+    @Test
+    public void testNoRequestMadeWhenEntryInCache() throws IOException {
+        ICacheAccess<String, CacheEntry> cache = getCache();
+        long expires = TimeUnit.DAYS.toMillis(1);
+        long testStart = System.currentTimeMillis();
+        cache.put("test",
+                new CacheEntry("cached entry".getBytes(StandardCharsets.UTF_8)),
+                createEntryAttributes(expires, 200, testStart, "eTag")
+                );
+        createHeadGetStub(WireMock.urlEqualTo("/test"), expires, testStart, "eTag", "mock entry");
+
+        TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(tileServer.url("/test"), "test");
+        Listener listener = submitJob(job, false);
+        tileServer.verify(0, WireMock.getRequestedFor(WireMock.anyUrl()));
+        assertArrayEquals("cached entry".getBytes(StandardCharsets.UTF_8), listener.data);
+    }
+
+    /**
+     * that request is made, when object is in cache, but force mode is used
+     * @throws IOException
+     */
+    @Test
+    public void testRequestMadeWhenEntryInCacheAndForce() throws IOException {
+        ICacheAccess<String, CacheEntry> cache = getCache();
+        long expires =  TimeUnit.DAYS.toMillis(1);
+        long testStart = System.currentTimeMillis();
+        cache.put("test",
+                new CacheEntry("cached dummy".getBytes(StandardCharsets.UTF_8)),
+                createEntryAttributes(expires, 200, testStart + expires, "eTag")
+                );
+        createHeadGetStub(WireMock.urlEqualTo("/test"), expires, testStart, "eTag", "mock entry");
+
+        TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(tileServer.url("/test"), "test");
+        Listener listener = submitJob(job, true);
+        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
+        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data);
+    }
+
+    /**
+     * Mock returns no cache-control / expires headers
+     * Expire time should be set to DEFAULT_EXPIRE_TIME
+     * @throws IOException
+     */
+    @Test
+    public void testSettingMinimumExpiryWhenNoExpires() throws IOException {
+        long testStart = System.currentTimeMillis();
+        tileServer.stubFor(
+                WireMock.get(WireMock.urlEqualTo("/test"))
+                .willReturn(WireMock.aResponse()
+                        .withBody("mock entry")
+                        )
+                );
+
+        TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(tileServer.url("/test"), "test");
+        Listener listener = submitJob(job, false);
+        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
+
+        assertTrue("Cache entry expiration is " + (listener.attributes.getExpirationTime() - testStart) + " which is not larger than " +
+                JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME + " (DEFAULT_EXPIRE_TIME)",
+                listener.attributes.getExpirationTime() >= testStart + JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME);
+
+        assertTrue("Cache entry expiration is " + (listener.attributes.getExpirationTime() - System.currentTimeMillis()) + " which is not less than " +
+                JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME + " (DEFAULT_EXPIRE_TIME)",
+                listener.attributes.getExpirationTime() <= System.currentTimeMillis() + JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME);
+
+        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data);
+    }
+
+    /**
+     * Mock returns expires headers, but Cache-Control
+     * Expire time should be set to max-age
+     * @throws IOException
+     */
+    @Test
+    public void testSettingExpireByMaxAge() throws IOException {
+        long testStart = System.currentTimeMillis();
+        long expires =  TimeUnit.DAYS.toSeconds(1);
+        tileServer.stubFor(
+                WireMock.get(WireMock.urlEqualTo("/test"))
+                .willReturn(WireMock.aResponse()
+                        .withHeader("Cache-control", "max-age=" + expires)
+                        .withBody("mock entry")
+                        )
+                );
+
+        TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(tileServer.url("/test"), "test");
+        Listener listener = submitJob(job, false);
+        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
+
+        assertTrue("Cache entry expiration is " + (listener.attributes.getExpirationTime() - testStart) + " which is not larger than " +
+                TimeUnit.SECONDS.toMillis(expires) + " (max-age)",
+                listener.attributes.getExpirationTime() >= testStart + TimeUnit.SECONDS.toMillis(expires));
+
+        assertTrue("Cache entry expiration is " + (listener.attributes.getExpirationTime() - System.currentTimeMillis()) + " which is not less than " +
+                TimeUnit.SECONDS.toMillis(expires) + " (max-age)",
+                listener.attributes.getExpirationTime() <= System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(expires));
+
+        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data);
+    }
+
+    /**
+     * mock returns expiration: JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME / 10
+     * minimum expire time: JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME / 2
+     * @throws IOException
+     */
+    @Test
+    public void testSettingMinimumExpiryByMinimumExpiryTimeLessThanDefault() throws IOException {
+        long testStart = System.currentTimeMillis();
+        int minimumExpiryTimeSeconds = (int)(JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME / 2);
+
+        createHeadGetStub(WireMock.urlEqualTo("/test"), (JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME / 10), testStart, "eTag", "mock entry");
+
+        TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(tileServer.url("/test"), "test", minimumExpiryTimeSeconds);
+        Listener listener = submitJob(job, false);
+        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
+        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data);
+
+
+        assertTrue("Cache entry expiration is " + (listener.attributes.getExpirationTime() - testStart) + " which is not larger than " +
+                TimeUnit.SECONDS.toMillis(minimumExpiryTimeSeconds) + " (minimumExpireTime)",
+                listener.attributes.getExpirationTime() >= testStart + TimeUnit.SECONDS.toMillis(minimumExpiryTimeSeconds) );
+
+        assertTrue("Cache entry expiration is " + (listener.attributes.getExpirationTime() - System.currentTimeMillis()) + " which is not less than " +
+                TimeUnit.SECONDS.toMillis(minimumExpiryTimeSeconds) + " (minimumExpireTime)",
+                listener.attributes.getExpirationTime() <= System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(minimumExpiryTimeSeconds));
+    }
+
+    /**
+     * mock returns expiration: JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME / 10
+     * minimum expire time: JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME * 2
+     * @throws IOException
+     */
+
+    @Test
+    public void testSettingMinimumExpiryByMinimumExpiryTimeGreaterThanDefault() throws IOException {
+        long testStart = System.currentTimeMillis();
+        int minimumExpiryTimeSeconds = (int)(JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME * 2);
+
+        createHeadGetStub(WireMock.urlEqualTo("/test"), (JCSCachedTileLoaderJob.DEFAULT_EXPIRE_TIME / 10), testStart, "eTag", "mock entry");
+
+        TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(tileServer.url("/test"), "test", minimumExpiryTimeSeconds);
+        Listener listener = submitJob(job, false);
+        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
+        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data);
+
+
+        assertTrue("Cache entry expiration is " + (listener.attributes.getExpirationTime() - testStart) + " which is not larger than " +
+                TimeUnit.SECONDS.toMillis(minimumExpiryTimeSeconds) + " (minimumExpireTime)",
+                listener.attributes.getExpirationTime() >= testStart + TimeUnit.SECONDS.toMillis(minimumExpiryTimeSeconds) );
+
+        assertTrue("Cache entry expiration is " + (listener.attributes.getExpirationTime() - System.currentTimeMillis()) + " which is not less than " +
+                TimeUnit.SECONDS.toMillis(minimumExpiryTimeSeconds) + " (minimumExpireTime)",
+                listener.attributes.getExpirationTime() <= System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(minimumExpiryTimeSeconds));
+    }
+
+    /**
+     * Check if verifying cache entries using HEAD requests work properly
+     * @throws IOException
+     */
+    @Test
+    public void testCheckUsingHead() throws IOException {
+        ICacheAccess<String, CacheEntry> cache = getCache();
+        long expires = TimeUnit.DAYS.toMillis(1);
+        long testStart = System.currentTimeMillis();
+        cache.put("test",
+                new CacheEntry("cached dummy".getBytes(StandardCharsets.UTF_8)),
+                createEntryAttributes(-1 * expires, 200, testStart, "eTag--gzip") // Jetty adds --gzip to etags when compressing output
+                );
+
+        tileServer.stubFor(
+                WireMock.get(WireMock.urlEqualTo("/test"))
+                .willReturn(WireMock.aResponse()
+                        .withHeader("Expires", TestUtils.getHTTPDate(testStart + expires))
+                        .withHeader("Last-Modified", Long.toString(testStart))
+                        .withHeader("ETag", "eTag") // Jetty adds "--gzip" suffix for compressed content
+                        .withBody("mock entry")
+                        )
+                );
+        tileServer.stubFor(
+                WireMock.head(WireMock.urlEqualTo("/test"))
+                .willReturn(WireMock.aResponse()
+                        .withHeader("Expires", TestUtils.getHTTPDate(testStart + expires))
+                        .withHeader("Last-Modified", Long.toString(testStart))
+                        .withHeader("ETag", "eTag--gzip") // but doesn't add to uncompressed
+                        )
+                );
+
+        TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(tileServer.url("/test"), "test");
+        Listener listener = submitJob(job, false); // cache entry is expired, no need to force refetch
+        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
+        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data);
+
+        // cache entry should be retrieved from cache
+        listener = submitJob(job, false);
+        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
+        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data);
+
+        // invalidate entry in cache
+        ICacheElement<String, CacheEntry> cacheEntry = cache.getCacheElement("test");
+        CacheEntryAttributes attributes = (CacheEntryAttributes)cacheEntry.getElementAttributes();
+        attributes.setExpirationTime(testStart - TimeUnit.DAYS.toMillis(1));
+        cache.put("test", cacheEntry.getVal(), attributes);
+
+        // because cache entry is invalid - HEAD request shall be made
+        tileServer.verify(0, WireMock.headRequestedFor(WireMock.urlEqualTo("/test"))); // no head requests were made until now
+        listener = submitJob(job, false);
+        tileServer.verify(1, WireMock.headRequestedFor(WireMock.urlEqualTo("/test"))); // verify head requests were made
+        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test"))); // verify no more get requests were made
+        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data);
+        assertTrue(listener.attributes.getExpirationTime() >= testStart + expires);
+
+        // cache entry should be retrieved from cache
+        listener = submitJob(job, false); // cache entry is expired, no need to force refetch
+        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
+        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
+        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), listener.data);
+    }
+
+    /**
+     * Check if server returns 304 - it will update cache attributes and not ask again for it
+     * @throws IOException
+     */
+    @Test
+    public void testCheckUsing304() throws IOException {
+        ICacheAccess<String, CacheEntry> cache = getCache();
+        long expires = TimeUnit.DAYS.toMillis(1);
+        long testStart = System.currentTimeMillis();
+        cache.put("test",
+                new CacheEntry("cached dummy".getBytes(StandardCharsets.UTF_8)),
+                createEntryAttributes(-1 * expires, 200, testStart, "eTag")
+                );
+
+        tileServer.stubFor(
+                WireMock.get(WireMock.urlEqualTo("/test"))
+                .willReturn(WireMock.status(304)
+                        .withHeader("Expires", TestUtils.getHTTPDate(testStart + expires))
+                        .withHeader("Last-Modified", Long.toString(testStart))
+                        .withHeader("ETag", "eTag")
+                        )
+                );
+
+        TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(tileServer.url("/test"), "test");
+        Listener listener = submitJob(job, false);
+        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
+        assertArrayEquals("cached dummy".getBytes(StandardCharsets.UTF_8), listener.data);
+        assertTrue(testStart + expires <= listener.attributes.getExpirationTime());
+        listener = submitJob(job, false);
+        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test"))); // no more requests were made
+    }
+
+    private void createHeadGetStub(UrlPattern url, long expires, long lastModified, String eTag, String body) {
+        tileServer.stubFor(
+                WireMock.get(url)
+                .willReturn(WireMock.aResponse()
+                        .withHeader("Expires", TestUtils.getHTTPDate(lastModified + expires))
+                        .withHeader("Last-Modified", Long.toString(lastModified))
+                        .withHeader("ETag", eTag)
+                        .withBody(body)
+                        )
+                );
+        tileServer.stubFor(
+                WireMock.head(url)
+                .willReturn(WireMock.aResponse()
+                        .withHeader("Expires", TestUtils.getHTTPDate(lastModified + expires))
+                        .withHeader("Last-Modified", Long.toString(lastModified))
+                        .withHeader("ETag", eTag)
+                        )
+                );
+    }
+
+    private CacheEntryAttributes createEntryAttributes(long maxAge, int responseCode, String eTag) {
+        long validTo = maxAge + System.currentTimeMillis();
+        return createEntryAttributes(maxAge, responseCode, validTo, eTag);
+    }
+
+    private CacheEntryAttributes createEntryAttributes(long expirationTime, int responseCode, long lastModification, String eTag) {
+        CacheEntryAttributes entryAttributes = new CacheEntryAttributes();
+        entryAttributes.setExpirationTime(lastModification + expirationTime);
+        entryAttributes.setResponseCode(responseCode);
+        entryAttributes.setLastModification(lastModification);
+        entryAttributes.setEtag(eTag);
+        return entryAttributes;
+    }
+
+    private static TestCachedTileLoaderJob getStatusLoaderJob(int responseCode)  {
         return new TestCachedTileLoaderJob("http://httpstat.us/" + responseCode, "key_" + responseCode);
     }
 
-    private static ICacheAccess<String, CacheEntry> getCache() throws IOException {
+    private static ICacheAccess<String, CacheEntry> getCache() {
         return JCSCacheManager.getCache("test");
     }
Index: /trunk/test/unit/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJobTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJobTest.java	(revision 13732)
+++ /trunk/test/unit/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJobTest.java	(revision 13733)
@@ -2,13 +2,35 @@
 package org.openstreetmap.josm.data.imagery;
 
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
 
+import org.apache.commons.jcs.access.behavior.ICacheAccess;
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
+import org.openstreetmap.gui.jmapviewer.Tile;
+import org.openstreetmap.gui.jmapviewer.interfaces.TileLoaderListener;
+import org.openstreetmap.gui.jmapviewer.tilesources.TMSTileSource;
+import org.openstreetmap.josm.TestUtils;
+import org.openstreetmap.josm.data.cache.BufferedImageCacheEntry;
+import org.openstreetmap.josm.data.cache.CacheEntryAttributes;
+import org.openstreetmap.josm.data.cache.JCSCacheManager;
 import org.openstreetmap.josm.testutils.JOSMTestRules;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
+
+import com.github.tomakehurst.wiremock.client.WireMock;
+import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
+import com.github.tomakehurst.wiremock.junit.WireMockRule;
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
@@ -24,5 +46,97 @@
     @Rule
     @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
-    public JOSMTestRules test = new JOSMTestRules();
+    public JOSMTestRules test = new JOSMTestRules().preferences();
+
+    /**
+     * mocked tile server
+     */
+    @Rule
+    public WireMockRule tileServer = new WireMockRule(WireMockConfiguration.options()
+            .dynamicPort());
+
+    @Before
+    public void clearCache() throws Exception {
+        getCache().clear();
+    }
+
+    private static ICacheAccess<String, BufferedImageCacheEntry> getCache() {
+        return JCSCacheManager.getCache("test");
+    }
+
+    private static class TestCachedTileLoaderJob extends TMSCachedTileLoaderJob {
+        private String url;
+        private String key;
+
+        TestCachedTileLoaderJob(TileLoaderListener listener, Tile tile, String key) throws IOException  {
+            this(listener, tile, key,  (int) TimeUnit.DAYS.toSeconds(1));
+        }
+
+        TestCachedTileLoaderJob(TileLoaderListener listener, Tile tile, String key, int minimumExpiry) throws IOException  {
+            super(listener, tile, getCache(), new TileJobOptions(30000, 30000, null, minimumExpiry),
+                    (ThreadPoolExecutor) Executors.newFixedThreadPool(1));
+
+            this.url = tile.getUrl();
+            this.key = key;
+        }
+
+        @Override
+        public URL getUrl() {
+            try {
+                return new URL(url);
+            } catch (MalformedURLException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        @Override
+        protected BufferedImageCacheEntry createCacheEntry(byte[] content) {
+            return new BufferedImageCacheEntry(content);
+        }
+
+        public CacheEntryAttributes getAttributes() {
+            return attributes;
+        }
+
+        @Override
+        public boolean isObjectLoadable() {
+            // use implementation from grand parent, to avoid calling getImage on dummy data
+            if (cacheData == null) {
+                return false;
+            }
+            return cacheData.getContent().length > 0;        }
+    }
+
+    private static class Listener implements TileLoaderListener {
+        private CacheEntryAttributes attributes;
+        private boolean ready;
+        private byte[] data;
+
+
+        @Override
+        public synchronized void tileLoadingFinished(Tile tile, boolean success) {
+            ready = true;
+            this.notifyAll();
+        }
+    }
+
+    private static class MockTile extends Tile {
+        MockTile(String url) {
+            super(new MockTileSource(url), 0, 0, 0);
+        }
+    }
+
+    private static class MockTileSource extends TMSTileSource {
+        private final String url;
+
+        public MockTileSource(String url) {
+            super(new ImageryInfo("mock"));
+            this.url = url;
+        }
+
+        @Override
+        public String getTileUrl(int zoom, int tilex, int tiley) throws IOException {
+            return url;
+        }
+    }
 
     /**
@@ -53,3 +167,148 @@
         assertEquals(expected, Utils.strip(m.group(1)));
     }
+
+    private TestCachedTileLoaderJob submitJob(MockTile tile, String key, boolean force) throws IOException {
+        return submitJob(tile, key, 0, force);
+    }
+
+    private TestCachedTileLoaderJob submitJob(MockTile tile, String key, int minimumExpiry, boolean force) throws IOException {
+        Listener listener = new Listener();
+        TestCachedTileLoaderJob job = new TestCachedTileLoaderJob(listener, tile, key, minimumExpiry);
+        job.submit(force);
+        synchronized (listener) {
+            while (!listener.ready) {
+                try {
+                    listener.wait();
+                } catch (InterruptedException e) {
+                    // do nothing, wait
+                    Logging.trace(e);
+                }
+            }
+        }
+        return job;
+    }
+
+    /**
+     * When tile server doesn't return any Expires/Cache-Control headers, expire should be at least MINIMUM_EXPIRES
+     * @throws IOException
+     */
+    @Test
+    public void testNoCacheHeaders() throws IOException {
+        long testStart = System.currentTimeMillis();
+        tileServer.stubFor(
+                WireMock.get(WireMock.urlEqualTo("/test"))
+                .willReturn(WireMock.aResponse()
+                        .withBody("mock entry")
+                        )
+                );
+
+        TestCachedTileLoaderJob job = submitJob(new MockTile(tileServer.url("/test")), "test", false);
+        assertExpirationAtLeast(testStart + TMSCachedTileLoaderJob.MINIMUM_EXPIRES.get(), job);
+        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), job.get().getContent());
+        job = submitJob(new MockTile(tileServer.url("/test")), "test", false); // submit another job for the same tile
+        // only one request to tile server should be made, second should come from cache
+        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
+        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), job.get().getContent());
+    }
+
+    /**
+     * When tile server doesn't return any Expires/Cache-Control headers, expire should be at least minimumExpires parameter
+     * @throws IOException
+     */
+    @Test
+    public void testNoCacheHeadersMinimumExpires() throws IOException {
+        noCacheHeadersMinimumExpires((int) TimeUnit.MILLISECONDS.toSeconds(TMSCachedTileLoaderJob.MINIMUM_EXPIRES.get() * 2));
+    }
+
+    /**
+     * When tile server doesn't return any Expires/Cache-Control headers, expire should be at least minimumExpires parameter,
+     * which is larger than MAXIMUM_EXPIRES
+     * @throws IOException
+     */
+
+    @Test
+    public void testNoCacheHeadersMinimumExpiresLargerThanMaximum() throws IOException {
+        noCacheHeadersMinimumExpires((int) TimeUnit.MILLISECONDS.toSeconds(TMSCachedTileLoaderJob.MAXIMUM_EXPIRES.get() * 2));
+    }
+
+    private void noCacheHeadersMinimumExpires(int minimumExpires) throws IOException {
+        long testStart = System.currentTimeMillis();
+        tileServer.stubFor(
+                WireMock.get(WireMock.urlEqualTo("/test"))
+                .willReturn(WireMock.aResponse()
+                        .withBody("mock entry")
+                        )
+                );
+        TestCachedTileLoaderJob job = submitJob(new MockTile(tileServer.url("/test")), "test", minimumExpires, false);
+        assertExpirationAtLeast(testStart + minimumExpires, job);
+        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), job.get().getContent());
+        job = submitJob(new MockTile(tileServer.url("/test")), "test", false); // submit another job for the same tile
+        // only one request to tile server should be made, second should come from cache
+        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
+        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), job.get().getContent());
+    }
+
+    /**
+     * When tile server returns Expires header shorter than MINIMUM_EXPIRES, we should cache if for at least MINIMUM_EXPIRES
+     * @throws IOException
+     */
+    @Test
+    public void testShortExpire() throws IOException {
+        long testStart = System.currentTimeMillis();
+        long expires = TMSCachedTileLoaderJob.MINIMUM_EXPIRES.get() / 2;
+        tileServer.stubFor(
+                WireMock.get(WireMock.urlEqualTo("/test"))
+                .willReturn(WireMock.aResponse()
+                        .withHeader("Expires", TestUtils.getHTTPDate(testStart + expires))
+                        .withBody("mock entry")
+                        )
+                );
+        TestCachedTileLoaderJob job = submitJob(new MockTile(tileServer.url("/test")), "test", false);
+        assertExpirationAtLeast(testStart + TMSCachedTileLoaderJob.MINIMUM_EXPIRES.get(), job);
+        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), job.get().getContent());
+        job = submitJob(new MockTile(tileServer.url("/test")), "test", false); // submit another job for the same tile
+        // only one request to tile server should be made, second should come from cache
+        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
+        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), job.get().getContent());
+    }
+
+    private void assertExpirationAtLeast(long duration, TestCachedTileLoaderJob job) {
+        assertTrue(
+                "Expiration time shorter by " +
+                        -1 * (job.getAttributes().getExpirationTime() - duration) +
+                        " than expected",
+                job.getAttributes().getExpirationTime() >= duration);
+    }
+
+    private void assertExpirationAtMost(long duration, TestCachedTileLoaderJob job) {
+        assertTrue(
+                "Expiration time longer by " +
+                        (job.getAttributes().getExpirationTime() - duration) +
+                        " than expected",
+                job.getAttributes().getExpirationTime() <= duration);
+    }
+
+
+    @Test
+    public void testLongExpire() throws IOException {
+        long testStart = System.currentTimeMillis();
+        long expires = TMSCachedTileLoaderJob.MAXIMUM_EXPIRES.get() * 2;
+        tileServer.stubFor(
+                WireMock.get(WireMock.urlEqualTo("/test"))
+                .willReturn(WireMock.aResponse()
+                        .withHeader("Expires", TestUtils.getHTTPDate(testStart + expires))
+                        .withBody("mock entry")
+                        )
+                );
+        TestCachedTileLoaderJob job = submitJob(new MockTile(tileServer.url("/test")), "test", false);
+        // give 1 second margin
+        assertExpirationAtMost(testStart + TMSCachedTileLoaderJob.MAXIMUM_EXPIRES.get() + TimeUnit.SECONDS.toMillis(1), job);
+
+        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), job.get().getContent());
+        job = submitJob(new MockTile(tileServer.url("/test")), "test", false); // submit another job for the same tile
+        // only one request to tile server should be made, second should come from cache
+        tileServer.verify(1, WireMock.getRequestedFor(WireMock.urlEqualTo("/test")));
+        assertArrayEquals("mock entry".getBytes(StandardCharsets.UTF_8), job.get().getContent());
+    }
+
 }
Index: /trunk/test/unit/org/openstreetmap/josm/data/imagery/WMSEndpointTileSourceTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/data/imagery/WMSEndpointTileSourceTest.java	(revision 13733)
+++ /trunk/test/unit/org/openstreetmap/josm/data/imagery/WMSEndpointTileSourceTest.java	(revision 13733)
@@ -0,0 +1,72 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.imagery;
+
+import static org.junit.Assert.assertEquals;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.TestUtils;
+import org.openstreetmap.josm.data.projection.Projections;
+import org.openstreetmap.josm.spi.preferences.Config;
+import org.openstreetmap.josm.testutils.JOSMTestRules;
+
+import com.github.tomakehurst.wiremock.WireMockServer;
+import com.github.tomakehurst.wiremock.client.WireMock;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
+public class WMSEndpointTileSourceTest {
+    /**
+     * Setup test
+     */
+    @Rule
+    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
+    public JOSMTestRules test = new JOSMTestRules().platform().projection();
+
+    @Test
+    public void testDefaultLayerSetInMaps() throws Exception {
+        WireMockServer getCapabilitiesMock = TestUtils.getWireMockServer();
+        String getCapabilitiesBody = new String(Files.readAllBytes(Paths.get(TestUtils.getTestDataRoot() + "wms/geofabrik-osm-inspector.xml")), "UTF-8");
+        // do not use withFileBody as it needs different directory layout :(
+        getCapabilitiesMock.stubFor(WireMock.get(WireMock.anyUrl()).willReturn(WireMock.aResponse().withBody(getCapabilitiesBody)));
+        getCapabilitiesMock.start();
+
+        WireMockServer mapsMock = TestUtils.getWireMockServer();
+        mapsMock.stubFor(WireMock.get(WireMock.anyUrl()).willReturn(WireMock.aResponse().withBody(
+                "<?xml version='1.0' encoding='UTF-8'?>\n" +
+                "<imagery xmlns=\"http://josm.openstreetmap.de/maps-1.0\">\n" +
+                "<entry>\n" +
+                "<name>OSM Inspector: Geometry</name>\n" +
+                "<id>OSM_Inspector-Geometry</id>\n" +
+                "<type>wms_endpoint</type>\n" +
+                "<url><![CDATA[" + getCapabilitiesMock.url("/any") + "]]></url>\n" +
+                "<icon>data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAAB5UlEQVQ4y4WTwWsTURDGfy8W1yYmXZOqtGJJFyGw6KF7CEigwYuS0kthrYUi4i0iORS9BU9hQdA/ILcixVBrwENKLz1FUBB0wWOwYFAqxUNYTZq6BfM8yC5d05iBObz3vfnmm3kz4sqDh/zP7szdlG5I+Of1zQ1xFA8xxI4GH2cjg4Cl+UUJcC4SJq6c7FPkKRlIoPQk0+NnuDwxHrhvuYd83+8OVuBlHouE/eDXzW8+/qO9DyHB0vyiVHoy2INSNiPdeg23XuPs3icmIoofPKXGmFJjjEUjgf4EFNi2TT6fJ5FI0Gg0ePrkMRfnbvn41QsJgEAJAQUdbYZyuQxAcvoSpmnydesFAF+cn8f2KUCw/fGt6GgzWJbF706bVCoFwGxyktnk5N8kB79QepL1zQ3xbOulCJWyGbkQHZWlbEZ6JIZhBDI1nQ5Np8P2zi4t9zAwGyNe3QALti11XSedTvsPYrEY73f3Bk+irusAnI6qrNy7z43sNUbFCQC6LYdCoYBbr/k1/2sh690HUalUaH7eIRxXA+6RFItF3HqN6+dP9REIb5lK2Yy0bdsHDMMgl8vRbTkAhOMqlmVhmibLq2ui7xsf1d+IV+0D3zVNw7KsPiXVapXnd2/Lodu4vLomTNMcSvIHY6bDkqJtEqIAAAAASUVORK5CYII=</icon>\n" +
+                "<attribution-text mandatory=\"true\">© Geofabrik GmbH, OpenStreetMap contributors, CC-BY-SA</attribution-text>\n" +
+                "<attribution-url>http://tools.geofabrik.de/osmi/</attribution-url>\n" +
+                "<max-zoom>18</max-zoom>\n" +
+                "<valid-georeference>true</valid-georeference>\n" +
+                "<defaultLayers>" +
+                "<layer name=\"single_node_in_way\" style=\"default\" />" +
+                "</defaultLayers>" +
+                "</entry>\n" +
+                "</imagery>"
+                )));
+        mapsMock.start();
+        Config.getPref().put("josm.url", mapsMock.url("/"));
+        ImageryLayerInfo.instance.loadDefaults(true, null, false);
+        assertEquals(1, ImageryLayerInfo.instance.getDefaultLayers().size());
+        ImageryInfo wmsImageryInfo = ImageryLayerInfo.instance.getDefaultLayers().get(0);
+        assertEquals("single_node_in_way", wmsImageryInfo.getDefaultLayers().get(0).getLayerName());
+        WMSEndpointTileSource tileSource = new WMSEndpointTileSource(wmsImageryInfo, Main.getProjection());
+        tileSource.initProjection(Projections.getProjectionByCode("EPSG:3857"));
+        assertEquals("https://tools.geofabrik.de/osmi/views/geometry/wxs?FORMAT=image/png&TRANSPARENT=TRUE&VERSION=1.1.1&SERVICE=WMS&REQUEST=GetMap&"
+                + "LAYERS=single_node_in_way&STYLES=default&"
+                + "SRS=EPSG:3857&WIDTH=512&HEIGHT=512&"
+                + "BBOX=20037506.6204108,-60112521.5836107,60112521.5836107,-20037506.6204108", tileSource.getTileUrl(1, 1, 1));
+
+    }
+}
Index: /trunk/test/unit/org/openstreetmap/josm/data/imagery/WMTSTileSourceTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/data/imagery/WMTSTileSourceTest.java	(revision 13732)
+++ /trunk/test/unit/org/openstreetmap/josm/data/imagery/WMTSTileSourceTest.java	(revision 13733)
@@ -8,9 +8,12 @@
 import java.io.IOException;
 import java.net.MalformedURLException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.util.ArrayList;
-import java.util.Collection;
-
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.ClassRule;
 import org.junit.Ignore;
-import org.junit.Rule;
 import org.junit.Test;
 import org.openstreetmap.gui.jmapviewer.tilesources.TemplatedTMSTileSource;
@@ -19,6 +22,12 @@
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryType;
+import org.openstreetmap.josm.data.imagery.WMTSTileSource.WMTSGetCapabilitiesException;
 import org.openstreetmap.josm.data.projection.Projections;
+import org.openstreetmap.josm.spi.preferences.Config;
 import org.openstreetmap.josm.testutils.JOSMTestRules;
+
+import com.github.tomakehurst.wiremock.WireMockServer;
+import com.github.tomakehurst.wiremock.client.WireMock;
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
@@ -28,4 +37,11 @@
  */
 public class WMTSTileSourceTest {
+
+    /**
+     * Setup test.
+     */
+    @ClassRule
+    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
+    public static JOSMTestRules test = new JOSMTestRules().preferences().platform();
 
     private ImageryInfo testImageryTMS = new ImageryInfo("test imagery", "http://localhost", "tms", null, null);
@@ -44,17 +60,13 @@
             "wmts/bug13975-multiple-tile-matrices-for-one-layer-projection.xml");
 
-    /**
-     * Setup test.
-     */
-    @Rule
-    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
-    public JOSMTestRules test = new JOSMTestRules();
 
     private static ImageryInfo getImagery(String path) {
         try {
-            return new ImageryInfo(
+            ImageryInfo ret = new ImageryInfo(
                     "test",
                     new File(path).toURI().toURL().toString()
                     );
+            ret.setImageryType(ImageryType.WMTS);
+            return ret;
         } catch (MalformedURLException e) {
             e.printStackTrace();
@@ -64,5 +76,5 @@
 
     @Test
-    public void testPseudoMercator() throws IOException {
+    public void testPseudoMercator() throws IOException, WMTSGetCapabilitiesException {
         Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
         WMTSTileSource testSource = new WMTSTileSource(testImageryPSEUDO_MERCATOR);
@@ -94,5 +106,5 @@
 
     @Test
-    public void testWALLONIE() throws IOException {
+    public void testWALLONIE() throws IOException, WMTSGetCapabilitiesException {
         Main.setProjection(Projections.getProjectionByCode("EPSG:31370"));
         WMTSTileSource testSource = new WMTSTileSource(testImageryWALLONIE);
@@ -114,5 +126,5 @@
     @Test
     @Ignore("disable this test, needs further working") // XXX
-    public void testWALLONIENoMatrixDimension() throws IOException {
+    public void testWALLONIENoMatrixDimension() throws IOException, WMTSGetCapabilitiesException {
         Main.setProjection(Projections.getProjectionByCode("EPSG:31370"));
         WMTSTileSource testSource = new WMTSTileSource(getImagery("test/data/wmts/WMTSCapabilities-Wallonie-nomatrixdimension.xml"));
@@ -138,5 +150,5 @@
 
     @Test
-    public void testWIEN() throws IOException {
+    public void testWIEN() throws IOException, WMTSGetCapabilitiesException {
         Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
         WMTSTileSource testSource = new WMTSTileSource(testImageryWIEN);
@@ -180,5 +192,5 @@
 
     @Test
-    public void testGeoportalTOPOPL() throws IOException {
+    public void testGeoportalTOPOPL() throws IOException, WMTSGetCapabilitiesException {
         Main.setProjection(Projections.getProjectionByCode("EPSG:4326"));
         WMTSTileSource testSource = new WMTSTileSource(testImageryTOPO_PL);
@@ -202,5 +214,5 @@
 
     @Test
-    public void testGeoportalORTOPL4326() throws IOException {
+    public void testGeoportalORTOPL4326() throws IOException, WMTSGetCapabilitiesException {
         Main.setProjection(Projections.getProjectionByCode("EPSG:4326"));
         WMTSTileSource testSource = new WMTSTileSource(testImageryORTO_PL);
@@ -211,5 +223,5 @@
 
     @Test
-    public void testGeoportalORTOPL2180() throws IOException {
+    public void testGeoportalORTOPL2180() throws IOException, WMTSGetCapabilitiesException {
         Main.setProjection(Projections.getProjectionByCode("EPSG:2180"));
         WMTSTileSource testSource = new WMTSTileSource(testImageryORTO_PL);
@@ -221,5 +233,5 @@
 
     @Test
-    public void testTicket12168() throws IOException {
+    public void testTicket12168() throws IOException, WMTSGetCapabilitiesException {
         Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
         WMTSTileSource testSource = new WMTSTileSource(testImagery12168);
@@ -231,15 +243,36 @@
 
     @Test
-    @Ignore("disabled as this needs user action") // XXX
     public void testTwoTileSetsForOneProjection() throws Exception {
         Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
-        WMTSTileSource testSource = new WMTSTileSource(testImageryOntario);
-        testSource.initProjection(Main.getProjection());
-        verifyTile(new LatLon(45.4105023, -75.7153702), testSource, 303751, 375502, 12);
-        verifyTile(new LatLon(45.4601306, -75.7617187), testSource, 1186, 1466, 4);
-    }
-
-    @Test
-    @Ignore("disabled as this needs user action") // XXX
+        ImageryInfo ontario = getImagery(TestUtils.getTestDataRoot() + "wmts/WMTSCapabilities-Ontario.xml");
+        ontario.setDefaultLayers(Arrays.asList(new DefaultLayer[] {
+                new DefaultLayer(ImageryType.WMTS, "Basemap_Imagery_2014", null, "default028mm")
+        }));
+        WMTSTileSource testSource = new WMTSTileSource(ontario);
+        testSource.initProjection(Main.getProjection());
+        assertEquals(
+                "http://maps.ottawa.ca/arcgis/rest/services/Basemap_Imagery_2014/MapServer/WMTS/tile/1.0.0/Basemap_Imagery_2014/default/default028mm/4/2932/2371.jpg",
+                testSource.getTileUrl(4, 2371, 2932));
+        verifyTile(new LatLon(45.4601306, -75.7617187), testSource, 2372, 2932, 4);
+        verifyTile(new LatLon(45.4602510, -75.7617187), testSource, 607232, 750591, 12);
+    }
+
+    @Test
+    public void testTwoTileSetsForOneProjectionSecondLayer() throws Exception {
+        Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
+        ImageryInfo ontario = getImagery(TestUtils.getTestDataRoot() + "wmts/WMTSCapabilities-Ontario.xml");
+        ontario.setDefaultLayers(Arrays.asList(new DefaultLayer[] {
+                new DefaultLayer(ImageryType.WMTS, "Basemap_Imagery_2014", null, "GoogleMapsCompatible")
+        }));
+        WMTSTileSource testSource = new WMTSTileSource(ontario);
+        testSource.initProjection(Main.getProjection());
+        assertEquals(
+                "http://maps.ottawa.ca/arcgis/rest/services/Basemap_Imagery_2014/MapServer/WMTS/tile/1.0.0/Basemap_Imagery_2014/default/GoogleMapsCompatible/4/2932/2371.jpg",
+                testSource.getTileUrl(4, 2371, 2932));
+        verifyMercatorTile(testSource, 74, 91, 8);
+        verifyMercatorTile(testSource, 37952, 46912, 17);
+    }
+
+    @Test
     public void testManyLayersScrollbars() throws Exception {
         Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
@@ -271,6 +304,6 @@
         Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
         ImageryInfo copy = new ImageryInfo(testMultipleTileMatrixForLayer);
-        Collection<DefaultLayer> defaultLayers = new ArrayList<>(1);
-        defaultLayers.add(new WMTSDefaultLayer("Mashhad_BaseMap_1", "default028mm"));
+        List<DefaultLayer> defaultLayers = new ArrayList<>(1);
+        defaultLayers.add(new DefaultLayer(ImageryType.WMTS, "Mashhad_BaseMap_1", null, "default028mm"));
         copy.setDefaultLayers(defaultLayers);
         WMTSTileSource testSource = new WMTSTileSource(copy);
@@ -286,11 +319,12 @@
      * Test WMTS dimension.
      * @throws IOException if any I/O error occurs
+     * @throws WMTSGetCapabilitiesException
      */
     @Test
-    public void testDimension() throws IOException {
+    public void testDimension() throws IOException, WMTSGetCapabilitiesException {
         Main.setProjection(Projections.getProjectionByCode("EPSG:21781"));
         ImageryInfo info = new ImageryInfo(testImageryGeoAdminCh);
-        Collection<DefaultLayer> defaultLayers = new ArrayList<>(1);
-        defaultLayers.add(new WMTSDefaultLayer("ch.are.agglomerationen_isolierte_staedte", "21781_26"));
+        List<DefaultLayer> defaultLayers = new ArrayList<>(1);
+        defaultLayers.add(new DefaultLayer(ImageryType.WMTS, "ch.are.agglomerationen_isolierte_staedte", null, "21781_26"));
         info.setDefaultLayers(defaultLayers);
         WMTSTileSource testSource = new WMTSTileSource(info);
@@ -300,4 +334,45 @@
                 testSource.getTileUrl(1, 2, 3)
                 );
+    }
+
+    @Test
+    public void testDefaultLayer() throws Exception {
+        // https://gibs.earthdata.nasa.gov/wmts/epsg3857/best/1.0.0/WMTSCapabilities.xml
+        WireMockServer getCapabilitiesMock = TestUtils.getWireMockServer();
+        String getCapabilitiesBody = new String(Files.readAllBytes(Paths.get(TestUtils.getTestDataRoot() + "wmts/getCapabilities-lots-of-layers.xml")), "UTF-8");
+        // do not use withFileBody as it needs different directory layout :(
+        getCapabilitiesMock.stubFor(WireMock.get(WireMock.anyUrl()).willReturn(WireMock.aResponse().withBody(getCapabilitiesBody)));
+        getCapabilitiesMock.start();
+
+        WireMockServer mapsMock = TestUtils.getWireMockServer();
+        mapsMock.stubFor(WireMock.get(WireMock.anyUrl()).willReturn(WireMock.aResponse().withBody(
+                "<?xml version='1.0' encoding='UTF-8'?>\n" +
+                "<imagery xmlns=\"http://josm.openstreetmap.de/maps-1.0\">\n" +
+                "<entry>\n" +
+                "<name>Landsat</name>\n" +
+                "<id>landsat</id>\n" +
+                "<type>wmts</type>\n" +
+                "<url><![CDATA[" + getCapabilitiesMock.url("/getcapabilities.xml") + "]]></url>\n" +
+                "<defaultLayers>" +
+                "<layer name=\"GEOGRAPHICALGRIDSYSTEMS.MAPS\" />" +
+                "</defaultLayers>" +
+                "</entry>\n" +
+                "</imagery>"
+                )));
+        mapsMock.start();
+        Config.getPref().put("josm.url", mapsMock.url("/"));
+
+        ImageryLayerInfo.instance.loadDefaults(true, null, false);
+
+        assertEquals(1, ImageryLayerInfo.instance.getDefaultLayers().size());
+        ImageryInfo wmtsImageryInfo = ImageryLayerInfo.instance.getDefaultLayers().get(0);
+        assertEquals(1, wmtsImageryInfo.getDefaultLayers().size());
+        assertEquals("GEOGRAPHICALGRIDSYSTEMS.MAPS", wmtsImageryInfo.getDefaultLayers().get(0).getLayerName());
+        WMTSTileSource tileSource = new WMTSTileSource(wmtsImageryInfo);
+        tileSource.initProjection(Projections.getProjectionByCode("EPSG:3857"));
+        assertEquals("http://wxs.ign.fr/61fs25ymczag0c67naqvvmap/geoportail/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&"
+                + "LAYER=GEOGRAPHICALGRIDSYSTEMS.MAPS"
+                + "&STYLE=normal&FORMAT=image/jpeg&tileMatrixSet=PM&tileMatrix=1&tileRow=1&tileCol=1", tileSource.getTileUrl(1, 1, 1));
+
     }
 
Index: /trunk/test/unit/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayerTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayerTest.java	(revision 13732)
+++ /trunk/test/unit/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayerTest.java	(revision 13733)
@@ -120,5 +120,6 @@
             return new TileLoaderFactory() {
                 @Override
-                public TileLoader makeTileLoader(TileLoaderListener listener, Map<String, String> headers) {
+                public TileLoader makeTileLoader(TileLoaderListener listener, Map<String, String> headers,
+                        long minimumExpiryTime) {
                     return null;
                 }
Index: /trunk/test/unit/org/openstreetmap/josm/gui/layer/WMTSLayerTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/gui/layer/WMTSLayerTest.java	(revision 13732)
+++ /trunk/test/unit/org/openstreetmap/josm/gui/layer/WMTSLayerTest.java	(revision 13733)
@@ -22,5 +22,5 @@
     @Rule
     @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
-    public JOSMTestRules test = new JOSMTestRules().timeout(20000);
+    public JOSMTestRules test = new JOSMTestRules().preferences().timeout(20000);
 
     /**
Index: /trunk/test/unit/org/openstreetmap/josm/io/imagery/WMSImageryTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/io/imagery/WMSImageryTest.java	(revision 13732)
+++ /trunk/test/unit/org/openstreetmap/josm/io/imagery/WMSImageryTest.java	(revision 13733)
@@ -6,5 +6,8 @@
 
 import java.io.IOException;
-import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
 
 import org.junit.Rule;
@@ -13,4 +16,7 @@
 import org.openstreetmap.josm.io.imagery.WMSImagery.WMSGetCapabilitiesException;
 import org.openstreetmap.josm.testutils.JOSMTestRules;
+
+import com.github.tomakehurst.wiremock.WireMockServer;
+import com.github.tomakehurst.wiremock.client.WireMock;
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
@@ -26,5 +32,5 @@
     @Rule
     @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
-    public JOSMTestRules test = new JOSMTestRules();
+    public JOSMTestRules test = new JOSMTestRules().platform().projection();
 
     /**
@@ -49,10 +55,23 @@
     @Test
     public void testTicket15730() throws IOException, WMSGetCapabilitiesException {
-        try (InputStream is = TestUtils.getRegressionDataStream(15730, "capabilities.xml")) {
-            WMSImagery wms = new WMSImagery();
-            wms.parseCapabilities(null, is);
-            assertEquals(1, wms.getLayers().size());
-            assertTrue(wms.getLayers().get(0).abstr.startsWith("South Carolina  NAIP Imagery 2017    Resolution: 100CM "));
-        }
+       WireMockServer wm = TestUtils.getWireMockServer(15730);
+       wm.stubFor(WireMock.get(WireMock.anyUrl()).willReturn(WireMock.aResponse().withBodyFile("capabilities.xml")));
+       wm.start();
+       WMSImagery wms = new WMSImagery(wm.url("capabilities.xml"));
+       assertEquals(1, wms.getLayers().size());
+       assertTrue(wms.getLayers().get(0).getAbstract().startsWith("South Carolina  NAIP Imagery 2017    Resolution: 100CM "));
+       wm.shutdown();
+    }
+
+    @Test
+    public void testNestedLayers() throws Exception {
+        WireMockServer getCapabilitiesMock = TestUtils.getWireMockServer();
+        String getCapabilitiesBody = new String(Files.readAllBytes(Paths.get(TestUtils.getTestDataRoot() + "wms/mapa-um-warszawa-pl.xml")), "UTF-8");
+        getCapabilitiesMock.stubFor(WireMock.get(WireMock.anyUrl()).willReturn(WireMock.aResponse().withBody(getCapabilitiesBody)));
+        getCapabilitiesMock.start();
+        WMSImagery wmsi = new WMSImagery(getCapabilitiesMock.url("/serwis"));
+        assertEquals(1, wmsi.getLayers().size());
+        assertEquals("Server WMS m.st. Warszawy", wmsi.getLayers().get(0).toString());
+        assertEquals(202, wmsi.getLayers().get(0).getChildren().size());
     }
 
@@ -64,9 +83,17 @@
     @Test
     public void testTicket16248() throws IOException, WMSGetCapabilitiesException {
-        try (InputStream is = TestUtils.getRegressionDataStream(16248, "capabilities.xml")) {
-            WMSImagery wms = new WMSImagery();
-            wms.parseCapabilities(null, is);
-            assertEquals("http://wms.hgis.cartomatic.pl/topo/3857/m25k", wms.getServiceUrl().toExternalForm());
-        }
+        Path capabilitiesPath = Paths.get(TestUtils.getRegressionDataFile(16248, "capabilities.xml"));
+        WireMockServer getCapabilitiesMock = TestUtils.getWireMockServer();
+        getCapabilitiesMock.stubFor(
+                WireMock.get(WireMock.anyUrl())
+                .willReturn(WireMock.aResponse().withBody(Files.readAllBytes(capabilitiesPath))));
+        getCapabilitiesMock.start();
+        WMSImagery wms = new WMSImagery(getCapabilitiesMock.url("any"));
+        assertEquals("http://wms.hgis.cartomatic.pl/topo/3857/m25k", wms.buildRootUrl());
+        assertEquals("wms.hgis.cartomatic.pl", wms.getLayers().get(0).getName());
+        assertEquals("http://wms.hgis.cartomatic.pl/topo/3857/m25kFORMAT=image/png&TRANSPARENT=TRUE&VERSION=1.1.1&SERVICE=WMS&REQUEST=GetMap&"
+                + "LAYERS=wms.hgis.cartomatic.pl&STYLES=&SRS={proj}&WIDTH={width}&HEIGHT={height}&BBOX={bbox}",
+                wms.buildGetMapUrl(wms.getLayers(), (List<String>)null, true));
     }
 }
+
