/**
   * @param request
   * @param response @TODO refactor and optimize code for initializing handler
   */
  public void doService(HttpServletRequest request, HttpServletResponse response) {
    if (response.isCommitted()) {
      LOG.logWarning("The response object is already committed!");
    }

    long startTime = System.currentTimeMillis();
    address = request.getRequestURL().toString();

    String service = null;
    try {
      OGCWebServiceRequest ogcRequest = OGCRequestFactory.create(request);

      LOG.logInfo(
          StringTools.concat(
              500,
              "Handling request '",
              ogcRequest.getId(),
              "' from '",
              request.getRemoteAddr(),
              "' to service: '",
              ogcRequest.getServiceName(),
              "'"));

      // get service from request
      service = ogcRequest.getServiceName().toUpperCase();

      // get handler instance
      ServiceDispatcher handler =
          ServiceLookup.getInstance().getHandler(service, request.getRemoteAddr());
      // dispatch request to specific handler
      handler.perform(ogcRequest, response);
    } catch (OGCWebServiceException e) {
      LOG.logError(e.getMessage(), e);
      sendException(response, e, request, service);
    } catch (ServiceException e) {
      if (e.getNestedException() instanceof OGCWebServiceException) {
        sendException(response, (OGCWebServiceException) e.getNestedException(), request, service);
      } else {
        sendException(
            response,
            new OGCWebServiceException(this.getClass().getName(), e.getMessage()),
            request,
            service);
      }
      LOG.logError(e.getMessage(), e);
    } catch (Exception e) {
      sendException(
          response,
          new OGCWebServiceException(this.getClass().getName(), e.getMessage()),
          request,
          service);
      LOG.logError(e.getMessage(), e);
    }
    if (LOG.isDebug()) {
      LOG.logDebug(
          "OGCServletController: request performed in "
              + Long.toString(System.currentTimeMillis() - startTime)
              + " milliseconds.");
    }
  }
  /**
   * reads a deegree WCS configuration file and performs a GetCoverage request Steps:
   *
   * <ul>
   *   <li>read configuration file
   *   <li>read a GetCoverage request object
   *   <li>perform the request
   * </ul>
   */
  public void _testGetCoverage1() {
    try {
      WCSConfiguration configuration =
          WCSConfiguration.create(Configuration.getWCSConfigurationURL());
      WCService service = new WCService(configuration);
      StringBuffer sb = new StringBuffer();
      sb.append(Configuration.PROTOCOL + "://" + Configuration.HOST)
          .append(':')
          .append(Configuration.PORT)
          .append(Configuration.WCS_WEB_CONTEXT)
          .append('/')
          .append(Configuration.WCS_SERVLET);

      String req =
          "<?xml version='1.0' encoding='UTF-8'?><GetCoverage "
              + "xmlns='http://www.opengis.net/wcs' xmlns:gml='http://www.opengis.net/gml' "
              + "service='WCS' version='1.0.0'><sourceCoverage>Mapneatline</sourceCoverage>"
              + "<domainSubset><spatialSubset><gml:Envelope srsName='EPSG:4326'>"
              + "<gml:pos dimension='2'>-1,-1</gml:pos><gml:pos dimension='2'>1,1"
              + "</gml:pos></gml:Envelope><gml:Grid dimension='2'><gml:limits>"
              + "<gml:GridEnvelope><gml:low>0 0</gml:low><gml:high>300 300</gml:high>"
              + "</gml:GridEnvelope></gml:limits><gml:axisName>x</gml:axisName>"
              + "<gml:axisName>y</gml:axisName></gml:Grid></spatialSubset></domainSubset>"
              + "<output><crs>EPSG:4326</crs><format>jpeg</format></output></GetCoverage>";
      StringReader reader = new StringReader(req);
      Document doc = XMLTools.parse(reader);

      GetCoverage desc = (GetCoverage) OGCRequestFactory.createFromXML(doc);
      ResultCoverage o = (ResultCoverage) service.doService(desc);
      BufferedImage bi = ((AbstractGridCoverage) o.getCoverage()).getAsImage(500, 500);

      FileOutputStream fos =
          new FileOutputStream(Configuration.getWCSBaseDir().getPath() + "/kannweg1.tif");
      ImageUtils.saveImage(bi, fos, "tif", 1);
      fos.close();
    } catch (Exception e) {
      fail(StringTools.stackTraceToString(e));
    }
  }
  /**
   * Sends the passed <code>OGCWebServiceException</code> to the calling client.
   *
   * @param response
   * @param e
   * @param request
   * @param service the service name, if known
   */
  private static void sendException(
      HttpServletResponse response,
      OGCWebServiceException e,
      HttpServletRequest request,
      String service) {
    LOG.logInfo("Sending OGCWebServiceException to client.");

    Map<?, ?> pmap = request.getParameterMap();
    Map<String, String> map = new HashMap<String, String>(pmap.size());
    for (Object o : pmap.keySet()) {
      String[] tmp = (String[]) pmap.get(o);
      for (int i = 0; i < tmp.length; i++) {
        tmp[i] = tmp[i].trim();
      }
      map.put(((String) o).toLowerCase(), arrayToString(tmp, ','));
    }

    boolean isWMS130 = false, isCSW = false, isWCTS = false, isWFS = false, isWFS100 = false;

    if (service == null) {
      service = map.get("service");
    }

    String version = map.get("version");

    if (service != null) {
      if ("wms".equalsIgnoreCase(service)) {
        isWMS130 = version != null && version.equals("1.3.0");
      }
      if ("wfs".equalsIgnoreCase(service)) {
        isWFS = true;
        isWFS100 = version != null && version.equals("1.0.0");
      }

      isCSW = "csw".equalsIgnoreCase(service);
      isWCTS = "wcts".equalsIgnoreCase(service);
      isWFS = "wfs".equalsIgnoreCase(service);
    } else {
      try {
        XMLFragment doc = new XMLFragment(request.getReader(), XMLFragment.DEFAULT_URL);
        service =
            OGCRequestFactory.getTargetService("", "", doc.getRootElement().getOwnerDocument());
        isCSW = "csw".equalsIgnoreCase(service);
        isWCTS = "wcts".equalsIgnoreCase(service);
        isWFS = "wfs".equalsIgnoreCase(service);
        isWFS100 =
            isWFS
                && doc.getRootElement().getAttribute("version") != null
                && doc.getRootElement().getAttribute("version").equals("1.0.0");
      } catch (SAXException e1) {
        // ignore
      } catch (IOException e1) {
        // ignore
      } catch (IllegalStateException e1) {
        // ignore, that happens in some tomcats
      }
    }

    try {
      XMLFragment doc;
      String contentType = "text/xml";

      if (!(isWMS130 || isCSW || isWCTS || isWFS)) {
        // apply the simplest of heuristics...
        String req = request.getRequestURI().toLowerCase();
        if (req.indexOf("csw") != -1) {
          isCSW = true;
        } else if (req.indexOf("wcts") != -1) {
          isWCTS = true;
        } else if (req.indexOf("wfs") != -1) {
          isWFS = true;
        }

        if (isWFS) {
          isWFS100 = req.indexOf("1.0.0") != -1;
        }

        if (!(isWMS130 || isCSW || isWCTS || isWFS || isWFS100)) {
          isWMS130 = version != null && version.equals("1.3.0");
        }
      }

      // send exception format INIMAGE etc. for WMS
      if (service != null && service.equalsIgnoreCase("wms")) {
        ServiceDispatcher handler = getInstance().getHandler(service, request.getRemoteAddr());
        if (handler instanceof WMSHandler) {
          WMSHandler h = (WMSHandler) handler;
          String format = map.get("format");
          String eFormat = map.get("exceptions");
          try {
            h.determineExceptionFormat(eFormat, format, version, response);
            h.writeServiceExceptionReport(e);
            return;
          } catch (Exception ex) {
            LOG.logDebug(
                "Error while sending the exception in special format."
                    + " Continuing in default mode.",
                ex);
          }
        }
      }

      if (isWMS130 || "wcs".equalsIgnoreCase(e.getLocator())) {
        doc = XMLFactory.exportNS(new ExceptionReport(new OGCWebServiceException[] {e}));
      } else if (isCSW) {
        doc =
            XMLFactory.exportExceptionReport(new ExceptionReport(new OGCWebServiceException[] {e}));
      } else if (isWCTS) {
        doc = org.deegree.owscommon_1_1_0.XMLFactory.exportException(e);
      } else if (isWFS100) {
        doc = XMLFactory.exportExceptionReportWFS100(e);
      } else if (isWFS) {
        doc = XMLFactory.exportExceptionReportWFS(e);
      } else {
        contentType = "application/vnd.ogc.se_xml";
        doc = XMLFactory.export(new ExceptionReport(new OGCWebServiceException[] {e}));
      }

      response.setContentType(contentType);
      OutputStream os = response.getOutputStream();
      doc.write(os);
      os.close();
    } catch (Exception ex) {
      LOG.logError("ERROR: " + ex.getMessage(), ex);
    }
  }