/**
   * @param wfs the {@link WFSDataStore} that sent the request
   * @param response a response handle to a service exception report
   * @return a {@link WFSException} containing the server returned exception report messages
   * @see WFSResponseParser#parse(WFSProtocol, WFSResponse)
   */
  public Object parse(WFS_1_1_0_DataStore wfs, WFSResponse response) {
    WFSConfiguration configuration = new WFSConfiguration();
    Parser parser = new Parser(configuration);
    InputStream responseStream = response.getInputStream();
    Charset responseCharset = response.getCharacterEncoding();
    Reader reader = new InputStreamReader(responseStream, responseCharset);
    Object parsed;
    try {
      parsed = parser.parse(reader);
      if (!(parsed instanceof net.opengis.ows10.ExceptionReportType)) {
        return new IOException("Unrecognized server error");
      }
    } catch (Exception e) {
      return new WFSException("Exception parsing server exception report", e);
    }
    net.opengis.ows10.ExceptionReportType report = (ExceptionReportType) parsed;
    List<ExceptionType> exceptions = report.getException();

    EObject originatingRequest = response.getOriginatingRequest();
    StringBuilder msg = new StringBuilder("WFS returned an exception.");
    msg.append(" Target URL: " + response.getTargetUrl());
    if (originatingRequest != null) {
      try {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        WFS_1_1_0_Protocol.encode(originatingRequest, configuration, out, Charset.forName("UTF-8"));
        String requestStr = out.toString("UTF-8");

        msg.append(". Originating request is: \n").append(requestStr).append("\n");
      } catch (Exception e) {
        LOGGER.log(Level.FINE, "Error encoding request for exception report", e);
      }
    }
    WFSException result = new WFSException(msg.toString());
    for (ExceptionType ex : exceptions) {
      result.addExceptionReport(String.valueOf(ex.getExceptionText()));
    }
    return result;
  }
  /** Writes out an OWS ExceptionReport document. */
  public void handleServiceException(ServiceException exception, Request request) {
    Ows10Factory factory = Ows10Factory.eINSTANCE;

    ExceptionType e = factory.createExceptionType();

    if (exception.getCode() != null) {
      e.setExceptionCode(exception.getCode());
    } else {
      // set a default
      e.setExceptionCode("NoApplicableCode");
    }

    e.setLocator(exception.getLocator());

    // add the message
    StringBuffer sb = new StringBuffer();
    OwsUtils.dumpExceptionMessages(exception, sb, true);
    e.getExceptionText().add(sb.toString());
    e.getExceptionText().addAll(exception.getExceptionText());

    if (verboseExceptions) {
      // add the entire stack trace
      // exception.
      e.getExceptionText().add("Details:");
      ByteArrayOutputStream trace = new ByteArrayOutputStream();
      exception.printStackTrace(new PrintStream(trace));
      e.getExceptionText().add(new String(trace.toByteArray()));
    }

    ExceptionReportType report = factory.createExceptionReportType();
    report.setVersion("1.0.0");
    report.getException().add(e);

    request.getHttpResponse().setContentType("application/xml");

    // response.setCharacterEncoding( "UTF-8" );
    OWSConfiguration configuration = new OWSConfiguration();

    Encoder encoder = new Encoder(configuration, configuration.schema());
    encoder.setIndenting(true);
    encoder.setIndentSize(2);
    encoder.setLineWidth(60);

    String schemaLocation =
        buildSchemaURL(baseURL(request.getHttpRequest()), "ows/1.0.0/owsExceptionReport.xsd");
    encoder.setSchemaLocation(org.geoserver.ows.xml.v1_0.OWS.NAMESPACE, schemaLocation);

    try {
      encoder.encode(
          report,
          org.geoserver.ows.xml.v1_0.OWS.EXCEPTIONREPORT,
          request.getHttpResponse().getOutputStream());
    } catch (Exception ex) {
      // throw new RuntimeException(ex);
      // Hmm, not much we can do here.  I guess log the fact that we couldn't write out the
      // exception and be done with it...
      LOGGER.log(Level.INFO, "Problem writing exception information back to calling client:", e);
    } finally {
      try {
        request.getHttpResponse().getOutputStream().flush();
      } catch (IOException ioe) {
      }
    }
  }