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;
 }
 // FREEHEP added synchronized
 public synchronized void markForRebuild(TargetInfo targetInfo) {
   //
   //     if it must already be rebuilt, no need to check further
   //
   if (!targetInfo.getRebuild()) {
     TargetHistory history =
         get(targetInfo.getConfiguration().toString(), targetInfo.getOutput().getName());
     if (history == null) {
       targetInfo.mustRebuild();
     } else {
       SourceHistory[] sourceHistories = history.getSources();
       File[] sources = targetInfo.getSources();
       if (sourceHistories.length != sources.length) {
         targetInfo.mustRebuild();
       } else {
         Hashtable sourceMap = new Hashtable(sources.length);
         for (int i = 0; i < sources.length; i++) {
           try {
             sourceMap.put(sources[i].getCanonicalPath(), sources[i]);
           } catch (IOException ex) {
             sourceMap.put(sources[i].getAbsolutePath(), sources[i]);
           }
         }
         for (int i = 0; i < sourceHistories.length; i++) {
           //
           //   relative file name, must absolutize it on output
           // directory
           //
           String absPath = sourceHistories[i].getAbsolutePath(outputDir);
           File match = (File) sourceMap.get(absPath);
           if (match != null) {
             try {
               match = (File) sourceMap.get(new File(absPath).getCanonicalPath());
             } catch (IOException ex) {
               targetInfo.mustRebuild();
               break;
             }
           }
           if (match == null || match.lastModified() != sourceHistories[i].getLastModified()) {
             targetInfo.mustRebuild();
             break;
           }
         }
       }
     }
   }
 }
 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;
   }
 }