/**
   * Transcodes the specified XML input in the specified output. All <code>TranscoderException
   * </code> exceptions not catched previously are tagged as fatal errors (ie. call the <code>
   * fatalError</code> method of the <code>ErrorHandler</code>).
   *
   * @param input the XML input to transcode
   * @param output the ouput where to transcode
   * @exception TranscoderException if an error occured while transcoding
   */
  public void transcode(TranscoderInput input, TranscoderOutput output) throws TranscoderException {

    Document document = null;
    String uri = input.getURI();
    if (input.getDocument() != null) {
      document = input.getDocument();
    } else {
      String parserClassname = (String) hints.get(KEY_XML_PARSER_CLASSNAME);
      String namespaceURI = (String) hints.get(KEY_DOCUMENT_ELEMENT_NAMESPACE_URI);
      String documentElement = (String) hints.get(KEY_DOCUMENT_ELEMENT);
      DOMImplementation domImpl = (DOMImplementation) hints.get(KEY_DOM_IMPLEMENTATION);

      if (parserClassname == null) {
        parserClassname = XMLResourceDescriptor.getXMLParserClassName();
      }
      if (domImpl == null) {
        handler.fatalError(
            new TranscoderException("Unspecified transcoding hints: KEY_DOM_IMPLEMENTATION"));
        return;
      }
      if (namespaceURI == null) {
        handler.fatalError(
            new TranscoderException(
                "Unspecified transcoding hints: KEY_DOCUMENT_ELEMENT_NAMESPACE_URI"));
        return;
      }
      if (documentElement == null) {
        handler.fatalError(
            new TranscoderException("Unspecified transcoding hints: KEY_DOCUMENT_ELEMENT"));
        return;
      }
      // parse the XML document
      DocumentFactory f = createDocumentFactory(domImpl, parserClassname);
      Object xmlParserValidating = hints.get(KEY_XML_PARSER_VALIDATING);
      boolean validating =
          xmlParserValidating != null && ((Boolean) xmlParserValidating).booleanValue();
      f.setValidating(validating);
      try {
        if (input.getInputStream() != null) {
          document =
              f.createDocument(
                  namespaceURI, documentElement, input.getURI(), input.getInputStream());
        } else if (input.getReader() != null) {
          document =
              f.createDocument(namespaceURI, documentElement, input.getURI(), input.getReader());
        } else if (input.getXMLReader() != null) {
          document =
              f.createDocument(namespaceURI, documentElement, input.getURI(), input.getXMLReader());
        } else if (uri != null) {
          document = f.createDocument(namespaceURI, documentElement, uri);
        }
      } catch (DOMException ex) {
        handler.fatalError(new TranscoderException(ex));
      } catch (IOException ex) {
        handler.fatalError(new TranscoderException(ex));
      }
    }
    // call the dedicated transcode method
    if (document != null) {
      try {
        transcode(document, uri, output);
      } catch (TranscoderException ex) {
        // at this time, all TranscoderExceptions are fatal errors
        handler.fatalError(ex);
        return;
      }
    }
  }