public TargetHistory get(String configId, String outputName) {
   TargetHistory targetHistory = (TargetHistory) history.get(outputName);
   if (targetHistory != null) {
     if (!targetHistory.getProcessorConfiguration().equals(configId)) {
       targetHistory = null;
     }
   }
   return targetHistory;
 }
 public void commit() throws IOException {
   //
   //   if not dirty, no need to update file
   //
   if (dirty) {
     //
     //   build (small) hashtable of config id's in history
     //
     Hashtable configs = new Hashtable(20);
     Enumeration elements = history.elements();
     while (elements.hasMoreElements()) {
       TargetHistory targetHistory = (TargetHistory) elements.nextElement();
       String configId = targetHistory.getProcessorConfiguration();
       if (configs.get(configId) == null) {
         configs.put(configId, configId);
       }
     }
     FileOutputStream outStream = new FileOutputStream(historyFile);
     OutputStreamWriter outWriter;
     //
     //   early VM's don't support UTF-8 encoding
     //       try and fallback to the default encoding
     //           otherwise
     String encodingName = "UTF-8";
     try {
       outWriter = new OutputStreamWriter(outStream, "UTF-8");
     } catch (UnsupportedEncodingException ex) {
       outWriter = new OutputStreamWriter(outStream);
       encodingName = outWriter.getEncoding();
     }
     BufferedWriter writer = new BufferedWriter(outWriter);
     writer.write("<?xml version='1.0' encoding='");
     writer.write(encodingName);
     writer.write("'?>\n");
     writer.write("<history>\n");
     StringBuffer buf = new StringBuffer(200);
     Enumeration configEnum = configs.elements();
     while (configEnum.hasMoreElements()) {
       String configId = (String) configEnum.nextElement();
       buf.setLength(0);
       buf.append("   <processor signature=\"");
       buf.append(CUtil.xmlAttribEncode(configId));
       buf.append("\">\n");
       writer.write(buf.toString());
       elements = history.elements();
       while (elements.hasMoreElements()) {
         TargetHistory targetHistory = (TargetHistory) elements.nextElement();
         if (targetHistory.getProcessorConfiguration().equals(configId)) {
           buf.setLength(0);
           buf.append("      <target file=\"");
           buf.append(CUtil.xmlAttribEncode(targetHistory.getOutput()));
           buf.append("\" lastModified=\"");
           buf.append(Long.toHexString(targetHistory.getOutputLastModified()));
           buf.append("\">\n");
           writer.write(buf.toString());
           SourceHistory[] sourceHistories = targetHistory.getSources();
           for (int i = 0; i < sourceHistories.length; i++) {
             buf.setLength(0);
             buf.append("         <source file=\"");
             buf.append(CUtil.xmlAttribEncode(sourceHistories[i].getRelativePath()));
             buf.append("\" lastModified=\"");
             buf.append(Long.toHexString(sourceHistories[i].getLastModified()));
             buf.append("\"/>\n");
             writer.write(buf.toString());
           }
           writer.write("      </target>\n");
         }
       }
       writer.write("   </processor>\n");
     }
     writer.write("</history>\n");
     writer.close();
     dirty = false;
   }
 }