@Override
  public void execute(UserMaximumExtentRequest request, UserMaximumExtentResponse response)
      throws Exception {
    String[] layers;
    ArrayList<String> tempLayers = new ArrayList<String>();
    String[] includeLayers = request.getLayerIds();
    boolean excludeRasterLayers = request.isExcludeRasterLayers();
    if (includeLayers != null && includeLayers.length > 0) {
      for (String layerId : includeLayers) {
        if (!securityContext.isLayerVisible(layerId)) {
          throw new GeomajasSecurityException(ExceptionCode.LAYER_NOT_VISIBLE, layerId);
        }
        Layer<?> l = configurationService.getLayer(layerId);
        if (null == l) {
          throw new GeomajasException(ExceptionCode.LAYER_NOT_FOUND, layerId);
        }
        if (!excludeRasterLayers || l.getLayerInfo().getLayerType() != LayerType.RASTER) {
          tempLayers.add(l.getId());
        }
      }
    }
    layers = tempLayers.toArray(new String[tempLayers.size()]);

    Layer<?> layer;
    Crs targetCrs = geoService.getCrs2(request.getCrs());

    if (layers.length == 0) {
      // return empty bbox
      response.setBounds(new Bbox());
    } else {
      Envelope extent = new Envelope();
      for (String layerId : layers) {
        layer = configurationService.getLayer(layerId);
        if (layer != null) {
          Envelope bounds;
          if (layer.getLayerInfo().getLayerType() == LayerType.RASTER) {
            bounds = securityContext.getVisibleArea(layerId).getEnvelopeInternal();
            CrsTransform transform = geoService.getCrsTransform(layer.getCrs(), targetCrs);
            bounds = geoService.transform(bounds, transform);
          } else {
            bounds = layerService.getBounds(layerId, targetCrs, null);
          }
          extent.expandToInclude(bounds);
        } else {
          log.warn("layer not found ?! " + layerId);
        }
      }
      response.setBounds(converterService.toDto(extent));
    }
  }
  /**
   * Finish initializing service.
   *
   * @throws IOException oop
   */
  @PostConstruct
  protected void init() throws IOException {
    // base configuration from XML file
    if (null != configurationFile) {
      log.debug("Get base configuration from {}", configurationFile);
      manager = new DefaultCacheManager(configurationFile);
    } else {
      manager = new DefaultCacheManager();
    }

    // cache for caching the cache configurations (hmmm, sounds a bit strange)
    Map<String, Map<CacheCategory, CacheService>> cacheCache =
        new HashMap<String, Map<CacheCategory, CacheService>>();

    // build default configuration
    if (null != defaultConfiguration) {
      setCaches(cacheCache, null, defaultConfiguration);
    }

    // build layer specific configurations
    for (Layer layer : layerMap.values()) {
      CacheInfo ci = configurationService.getLayerExtraInfo(layer.getLayerInfo(), CacheInfo.class);
      if (null != ci) {
        setCaches(cacheCache, layer, ci);
      }
    }
  }
  @Test
  public void testConvertMaxExtent() throws Exception {
    Layer layer = configurationService.getLayer("countries");
    Bbox configMaxExtent = layer.getLayerInfo().getMaxExtent();
    Assert.assertEquals(-85.05112877980659, configMaxExtent.getX(), DOUBLE_TOLERANCE);
    Assert.assertEquals(-85.05112877980659, configMaxExtent.getY(), DOUBLE_TOLERANCE);
    Assert.assertEquals(170.102257, configMaxExtent.getWidth(), DOUBLE_TOLERANCE);
    Assert.assertEquals(170.102257, configMaxExtent.getHeight(), DOUBLE_TOLERANCE);

    GetMapConfigurationRequest request = new GetMapConfigurationRequest();
    request.setApplicationId("simplevectors");
    request.setMapId("coordTestMap");
    GetMapConfigurationResponse response =
        (GetMapConfigurationResponse)
            dispatcher.execute(GetMapConfigurationRequest.COMMAND, request, null, "en");
    if (response.isError()) {
      response.getErrors().get(0).printStackTrace();
    }
    Assert.assertFalse(response.isError());
    ClientMapInfo mapInfo = response.getMapInfo();
    Assert.assertNotNull(mapInfo);
    Bbox mapMaxExtent = mapInfo.getLayers().get(0).getMaxExtent();
    // these values were registered during a first run, they have *not* been externally verified
    Assert.assertEquals(-9467848.347161204, mapMaxExtent.getX(), DOUBLE_TOLERANCE);
    Assert.assertEquals(-2.0037508342789236E7, mapMaxExtent.getY(), DOUBLE_TOLERANCE);
    Assert.assertEquals(1.8935696632026553E7, mapMaxExtent.getWidth(), DOUBLE_TOLERANCE);
    Assert.assertEquals(4.007501596344786E7, mapMaxExtent.getHeight(), DOUBLE_TOLERANCE);

    // user data
    ClientUserDataInfo info = mapInfo.getUserData();
    Assert.assertNotNull(info);
    Assert.assertTrue(info instanceof ClientApplicationInfo.DummyClientUserDataInfo);
    Assert.assertEquals(
        "some data", ((ClientApplicationInfo.DummyClientUserDataInfo) info).getDummy());

    // widget data
    Assert.assertNotNull(mapInfo.getWidgetInfo());
    Assert.assertNull(mapInfo.getWidgetInfo("mapSelect"));
    Assert.assertNotNull(mapInfo.getWidgetInfo("layerTree"));
    Assert.assertEquals(
        "layer1, layer2",
        ((ClientApplicationInfo.DummyClientWidgetInfo) mapInfo.getWidgetInfo("layerTree"))
            .getDummy());
    // Default value of ViewBounds LimitOption
    BoundsLimitOption boundsLimitOption = mapInfo.getViewBoundsLimitOption();
    Assert.assertNotNull(info);
    Assert.assertEquals(BoundsLimitOption.COMPLETELY_WITHIN_MAX_BOUNDS, boundsLimitOption);
  }