/**
  * Write key definition XML configuration file
  *
  * @param keydefFile key definition file
  * @param keydefs list of key definitions
  * @throws DITAOTException if writing configuration file failed
  */
 public static void writeKeydef(final File keydefFile, final Collection<KeyDef> keydefs)
     throws DITAOTException {
   XMLSerializer keydef = null;
   try {
     keydef = XMLSerializer.newInstance(new FileOutputStream(keydefFile));
     keydef.writeStartDocument();
     keydef.writeStartElement(ELEMENT_STUB);
     for (final KeyDef k : keydefs) {
       keydef.writeStartElement(ELEMENT_KEYDEF);
       keydef.writeAttribute(ATTRIBUTE_KEYS, k.keys);
       if (k.href != null) {
         keydef.writeAttribute(ATTRIBUTE_HREF, k.href);
       }
       if (k.source != null) {
         keydef.writeAttribute(ATTRIUBTE_SOURCE, k.source);
       }
       keydef.writeEndElement();
     }
     keydef.writeEndDocument();
   } catch (final Exception e) {
     throw new DITAOTException(
         "Failed to write key definition file " + keydefFile + ": " + e.getMessage(), e);
   } finally {
     if (keydef != null) {
       try {
         keydef.close();
       } catch (final IOException e) {
       }
     }
   }
 }
  public AbstractPipelineOutput execute(final AbstractPipelineInput input) throws DITAOTException {
    if (logger == null) {
      throw new IllegalStateException("Logger not set");
    }
    final Date startTime = TimingUtils.getNowTime();

    try {
      logger.logInfo(moduleStartMsg);
      parseInputParameters(input);

      // set grammar pool flag
      GrammarPoolManager.setGramCache(gramcache);

      reader = new GenListModuleReader();
      reader.setLogger(logger);
      reader.initXMLReader(ditaDir, xmlValidate, rootFile, setSystemid);
      final FilterUtils filterUtils = parseFilterFile();
      reader.setFilterUtils(filterUtils);
      reader.setOutputUtils(outputUtils);

      addToWaitList(inputFile);
      processWaitList();
      // Depreciated function
      // The base directory does not change according to the referenceing
      // topic files in the new resolution
      updateBaseDirectory();
      refactoringResult();
      outputResult();
      schemekeydef.writeEndDocument();
      schemekeydef.close();
      // Added by William on 2009-06-25 for req #12014 start
      // write the end tag
      export.write("</stub>");
      // close the steam
      export.close();
      // Added by William on 2009-06-25 for req #12014 end
    } catch (final DITAOTException e) {
      throw e;
    } catch (final SAXException e) {
      throw new DITAOTException(e.getMessage(), e);
    } catch (final Exception e) {
      throw new DITAOTException(e.getMessage(), e);
    } finally {

      logger.logInfo(moduleEndMsg + TimingUtils.reportElapsedTime(startTime));
    }

    return null;
  }