protected InputStream sanitizeXmlDocument(DefaultHandler handler, InputStream inputStream)
      throws S3ServiceException {
    if (!properties.getBoolProperty("xmlparser.sanitize-listings", true)) {
      // No sanitizing will be performed, return the original input stream unchanged.
      return inputStream;
    } else {
      if (log.isDebugEnabled()) {
        log.debug("Sanitizing XML document destined for handler " + handler.getClass());
      }

      InputStream sanitizedInputStream = null;

      try {
        /* Read object listing XML document from input stream provided into a
         * string buffer, so we can replace troublesome characters before
         * sending the document to the XML parser.
         */
        StringBuffer listingDocBuffer = new StringBuffer();
        BufferedReader br =
            new BufferedReader(new InputStreamReader(inputStream, Constants.DEFAULT_ENCODING));

        char[] buf = new char[8192];
        int read = -1;
        while ((read = br.read(buf)) != -1) {
          listingDocBuffer.append(buf, 0, read);
        }
        br.close();

        // Replace any carriage return (\r) characters with explicit XML
        // character entities, to prevent the SAX parser from
        // misinterpreting 0x0D characters as 0x0A.
        String listingDoc = listingDocBuffer.toString().replaceAll("\r", "
");

        sanitizedInputStream =
            new ByteArrayInputStream(listingDoc.getBytes(Constants.DEFAULT_ENCODING));
      } catch (Throwable t) {
        try {
          inputStream.close();
        } catch (IOException e) {
          if (log.isErrorEnabled()) {
            log.error(
                "Unable to close response InputStream after failure sanitizing XML document", e);
          }
        }
        throw new S3ServiceException(
            "Failed to sanitize XML document destined for handler " + handler.getClass(), t);
      }
      return sanitizedInputStream;
    }
  }
 /**
  * Parses an XML document from an input stream using a document handler.
  *
  * @param handler the handler for the XML document
  * @param inputStream an input stream containing the XML document to parse
  * @throws S3ServiceException any parsing, IO or other exceptions are wrapped in an
  *     S3ServiceException.
  */
 protected void parseXmlInputStream(DefaultHandler handler, InputStream inputStream)
     throws S3ServiceException {
   try {
     if (log.isDebugEnabled()) {
       log.debug("Parsing XML response document with handler: " + handler.getClass());
     }
     BufferedReader breader =
         new BufferedReader(new InputStreamReader(inputStream, Constants.DEFAULT_ENCODING));
     xr.setContentHandler(handler);
     xr.setErrorHandler(handler);
     xr.parse(new InputSource(breader));
   } catch (Throwable t) {
     try {
       inputStream.close();
     } catch (IOException e) {
       if (log.isErrorEnabled()) {
         log.error("Unable to close response InputStream up after XML parse failure", e);
       }
     }
     throw new S3ServiceException(
         "Failed to parse XML document with handler " + handler.getClass(), t);
   }
 }