/*
******************************************************************************
* Copyright (C) 1996-2000, International Business Machines Corporation and   *
* others. All Rights Reserved.                                               *
******************************************************************************
*
* $Source: /usr/cvs/icu4j/icu4j/src/com/ibm/icu/impl/ByteTrie.java,v $ 
* $Date: 2002/03/02 02:20:01 $ 
* $Revision: 1.5 $
*
******************************************************************************
*/

package com.ibm.icu.dev.tool.xmlcomparator;

/**
 * @author ram
 *
 * This tool compares locale data in XML format and generates HTML and XML reports
 */
import java.io.*;
import java.util.*;
import java.io.PrintWriter;
import java.io.File;
import java.io.FileReader;
import java.io.BufferedReader;
import java.text.DecimalFormat;
import java.util.Calendar;


import java.util.Locale;

// DOM imports
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

// Needed JAXP classes
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

// SAX2 imports
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import com.ibm.icu.text.Normalizer;
import com.ibm.icu.lang.UCharacter;

public class XMLComparator {
    String[] fileNames; 
    private static final short OPT_SUN_JDK = 0x001;
    private static final short OPT_IBM_JDK = 0x002;
    private static final short OPT_WINDOWS = 0x004;
    private static final short OPT_HP_UX   = 0x008;
    private static final short OPT_SOLARIS = 0x010;
    private static final short OPT_IBM_TOR = 0x020;
    private static final short OPT_APPLE   = 0x040;
    private static final short OPT_ICU     = 0x080;
    private static final short OPT_OTHER   = 0x100;
    private static final short OPT_SOURCE  = 0x120;
    private static final short OPT_DEST    = 0x140;
    private static final short OPT_OUT1    = 0x160;
    private static final short OPT_OUT2    = 0x180;
    private static final short OPT_UNKNOWN = 0x1000;
    
    private static final String POSIX= "0";/* NO inheritence of locale data */
    private static final String ICU  = "1";/* Supports inheritence of locale data*/
    private static final String USER_OPTIONS[][] = {
        {"-sun_jdk", "sun_jdk",ICU}, 
        {"-ibm_jdk", "ibm_jdk",ICU},
        {"-windows", "windows", POSIX},
        {"-hp_ux",   "hp_ux",POSIX }, 
        {"-solaris", "solaris",POSIX },
        {"-ibm_tor", "ibm_toronto",POSIX},
        {"-apple",   "apple", POSIX},
        {"-icu",     "icu",ICU},
        {"-other",   "other", POSIX},
        {"-s",null,null},
        {"-d",null, null},
        {"-out1",null,null},
    };
    
    Hashtable optionTable = new Hashtable();
    private String sourceFolder = ".";
    private String destFolder = ".";
    private boolean out1 = false;
    private boolean out2 = false;
    
    public static void main(String[] args){
        XMLComparator comparator = new XMLComparator();
        comparator.processArgs(args);    
        
    }
    
    ArrayList doesNotExist = new ArrayList();
    ArrayList notAvailable = new ArrayList();
      
    /*
     * This application will compare different locale data xml files
     * conforming to localeElements.dtd and produces an xml file file
     * in the format
     */ 
                        
    Document resultDocument;
    String localeStr;    
    Locale locale;
    Calendar cal = Calendar.getInstance();
                 
    private void processArgs(String[] args){
        short options = identifyOptions(args);
        if ((args.length < 2) || ((options & OPT_UNKNOWN) != 0)) {
            printUsage();
            return;
        }
        boolean warning[] = new boolean[1];
        warning[0] = false;
        Enumeration enum = optionTable.keys();
        try{
            
            resultDocument = parse(sourceFolder+File.separator+"ResultXML.xml");
            
	        localeStr  = goldFileName.substring(goldFileName.lastIndexOf(File.separatorChar)+1,goldFileName.indexOf('.'));
	        locale = new Locale(localeStr.substring(0,localeStr.indexOf('_')),localeStr.substring(localeStr.indexOf('_')+1,localeStr.length()));
            OutputStreamWriter os1 = new OutputStreamWriter(new FileOutputStream(destFolder+File.separator+locale+".xml"),encoding);
	        OutputStreamWriter os2 = new OutputStreamWriter(new FileOutputStream(destFolder+File.separator+locale+".html"),encoding);
	            
            for(;enum.hasMoreElements();){
                String key = (String)enum.nextElement();
                String fileName = (String) optionTable.get(key);
                compare(goldFileName,goldKey, fileName,key,out1);
                
            }
           
	
            Iterator iter =doesNotExist.iterator();
            while(iter.hasNext()){
                  String key = (String)iter.next();
                  NodeList list = resultDocument.getElementsByTagName(key);
                  addNodeValue(list,key,"S.N.A",null);
            }
            notAvailable.add("solaris");
            notAvailable.add("apple");
            notAvailable.add("other");
            notAvailable.add("open_office");
            iter =notAvailable.iterator();
            while(iter.hasNext()){
                  String key = (String)iter.next();
                  NodeList list = resultDocument.getElementsByTagName(key);
                  addNodeValue(list,key,"S.N.A",null);
            }

            PrintWriter writer1 = new PrintWriter(os1);
            PrintWriter writer2 = new PrintWriter(os2);
            print(writer1,resultDocument);
            if(out1){
                printHTML_1(writer2);
            }else{
                printHTML(writer2);
            }
        }catch(Exception e){
            e.printStackTrace();
        }
            
    }
    
    private void printUsage() {
        System.err.println("Usage: XMLComparator [<option>:<gold>] filename1 [option] filename2 ... \n"+
                           " XMLComparator [-sun_jdk:gold]  filename" +
                           " [-ibm_jdk] filename [-windows] filename" +
                           " [-hp_ux]  filename [-solaris] filename"  +
                           " [-ibm_tor] filename [-apple] filename"   +
                           " [-icu] filename [-other] filename"  
                           );
    }
    private String goldFileName; 
    private String goldKey;

    private short identifyOptions(String[] options) {
        short result = 0;
        for (int j = 0; j < options.length; j++) {
            String option = options[j];
            boolean isGold = false;
            if (option.startsWith("-")) {
                if(option.indexOf(":gold")>0){
                    option = option.substring(0,option.indexOf(":"));
                    isGold = true;    
                }
                boolean optionRecognized = false;
                for (short i = 0; i < USER_OPTIONS.length; i++) {
                   
                    if (USER_OPTIONS[i][0].equals(option)) {
                        result |= (short)(1 << i);
                        optionRecognized = true;
                        if(i==9){
                            sourceFolder = options[++j];
                        }else if(i==10){
                            destFolder = options[++j];
                        }else if(i==11){
                            out1=true;
                        }else{
                            if(!isGold){
                                optionTable.put(USER_OPTIONS[i][1],options[++j]);
                            }else{
                                goldFileName = options[++j];
                                goldKey      = USER_OPTIONS[i][1];
                            }
                        }
                        break;
                    }
                }
                if (!optionRecognized) {
                    result |= OPT_UNKNOWN;
                }
            }
        }
        return result;
    }
    
    private void   printHTML(PrintWriter writer){
        NodeList list= resultDocument.getElementsByTagName("difference_element");
        writer.println("<html>\n"+
                           "    <head>\n"+
                           "        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n"+
                           "        <title>"+locale+"</title>\n"+
                           "    </head>\n"+
                           "    <body>\n"+
                           "        <p><b>"+locale+"</b></p>\n"+
                           "        <table border=\"1\" cellspacing=\"0\">\n"+
                           "            <tr>\n"+
                           "                <th>ParentNode</th>\n"+
                           "                <th>Name</th>\n"+
                           "                <th>ID</th>\n"+
                           "                <th>ICU 2.1</th>\n"+
                           "                <th>IBM Toronto</th>\n"+
                           "                <th>Windows 2000</th>\n"+
                           "                <th>Sun JDK 1.3</th>\n"+
                           "                <th>IBM JDK 1.3</th>\n"+
                           "                <th>Solaris</th>\n"+
                           "                <th>Apple</th>\n"+
                           "                <th>HPUX 11</th>\n"+
                           "                <th>Open Office</th>\n"+
                           "                <th>Other</th>\n"+
                           "            </tr>\n");
                           
        for(int i =0; i<list.getLength();i++){
             Node diffElem = list.item(i);
             writer.println("            <tr>\n");
             NamedNodeMap attrb = diffElem.getAttributes();
             if(attrb.item(0).getNodeValue().equals("test")) continue;
             writer.println("                <td>" + attrb.item(0).getNodeValue()+"</td>");
             writer.println("                <td>" + attrb.item(1).getNodeValue()+"</td>");
             //attribute 2 is ignored
             writer.println("                <td>" + attrb.item(3).getNodeValue()+"</td>");
             
             NodeList childList = diffElem.getChildNodes();
             for(int j=0; j<childList.getLength();j++){
                 Node current = childList.item(j);
                 if(current!=null && current.getNodeType()==Node.ELEMENT_NODE){
                      //System.out.println(current.getNodeName());
                      String val = current.getFirstChild().getNodeValue();
                      if(val==null || (val=trim(val)).equals("")) val="&nbsp;";
                      writer.println("                <td>"+val+"</td>");
                 }
             }       

              writer.println("            </tr>\n");
        }   
        writer.println( "        </table>\n"+
                            "    </body>\n"+
                            "</html>");
        writer.flush();
    }
    private void   printHTML_1(PrintWriter writer){
        NodeList list= resultDocument.getElementsByTagName("difference_element");
        writer.println("<html>\n"+
                           "    <head>\n"+
                           "        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n"+
                           "        <title>"+localeStr+"</title>\n"+
                           "    </head>\n"+
                           "    <body>\n"+
                           "        <p><b>"+localeStr+"("+locale.getDisplayLanguage()+"_"+locale.getDisplayCountry()+")</b></p>\n"+
                           "        <table border=\"1\" cellspacing=\"0\">\n"+
                           "            <tr>\n"+
                           "                <th>ParentNode</th>\n"+
                           "                <th>Name</th>\n"+
                           "                <th>ID</th>\n"+
                           "                <th>ICU 2.1</th>\n"+
                           "                <th>IBM Toronto</th>\n"+
                           "                <th>Windows 2000</th>\n"+
                           "                <th>Sun JDK 1.3</th>\n"+
                           "                <th>IBM JDK 1.3</th>\n"+
                           "                <th>Solaris</th>\n"+
                           "                <th>Apple</th>\n"+
                           "                <th>HPUX 11</th>\n"+
                           "                <th>Open Office</th>\n"+
                           "                <th>Other</th>\n"+
                           "            </tr>\n");
        
        Hashtable colorHash = new Hashtable();
        colorHash.put("icu","#D3D3D3");        
        colorHash.put("ibm_toronto","#ADD8E6");
        colorHash.put("windows","#98FB98");
        colorHash.put("sun_jdk","#B0C4DE");
        colorHash.put("ibm_jdk","#FAFAD2");
        colorHash.put("hp_ux","#FFE4B5");
        colorHash.put("apple","#F5F5DC");
        colorHash.put("solaris","#E0FFFF");
        colorHash.put("other","#E0FFFF");
        boolean hasData =false;          
        for(int i =0; i<list.getLength();i++){
             Node diffElem = list.item(i);
             NamedNodeMap attrb = diffElem.getAttributes();
            
             if(attrb.item(0).getNodeValue().equals("test") || attrb.item(0).getNodeValue().equals("identity")) continue;
             
             writer.println("            <tr>\n");
             writer.println("                <td>" + attrb.item(0).getNodeValue()+"</td>");
             writer.println("                <td>" + attrb.item(1).getNodeValue()+"</td>");
             //attribute 2 is ignored
             writer.println("                <td>" + attrb.item(3).getNodeValue()+"</td>");
             
             NodeList childList = diffElem.getChildNodes();
             for(int j=0; j<childList.getLength();j++){
                 Node current = childList.item(j);
                 if(current!=null && current.getNodeType()==Node.ELEMENT_NODE){
                      
                      //System.out.println(current.getNodeName());
                      String val = current.getFirstChild().getNodeValue();
                      if(val==null || (val=trim(val)).equals("")) val="D.N.A";
                      String color="#FFFFFF";
                      if(!val.equals("S.N.A") && !val.equals("D.N.A")){
	                      for(int k=0; k<childList.getLength();k++){
	                         Node n = childList.item(k);
	                         if(n!=null && n.getNodeType()==Node.ELEMENT_NODE){
                                String nVal =n.getFirstChild().getNodeValue();
                                //-ibm_jdk c:\NLTC\IBMJDK\XML\cs_CZ.xml -sun_jdk c:\NLTC\Java\xml\cs_CZ.xml -windows c:\NLTC\windows\xml\cs_CZ.xml -hp_ux c:\NLTC\hp\xml\cs_CZ.xml
                                
                                if( (!nVal.equals("S.N.A") && !nVal.equals("D.N.A"))&&
                                    (
                                     val.equals(nVal) ||
                                     ((attrb.item(1).getNodeValue().equals("pattern"))&&
                                     comparePatterns(val,nVal))||
                                     ((attrb.item(0).getNodeValue().equals("patterns"))&&
                                     comparePatterns(val,nVal))
                                    )
                                  ){ 
		                            String str = (String)colorHash.get(n.getNodeName());
		                            if(str!=null){
		                                color=str;
		                            }
                                   
		                            break;
                                   
                                }
	                         }
	                      }
                      }
                      NamedNodeMap attList = current.getAttributes();
                      if(attList.getNamedItem("case_diff").getNodeValue().equals("false")){
                        writer.println("                <td bgcolor="+color+">"+val+"</td>");
                      }else{
                        writer.println("                <td bgcolor="+color+">"+
                                       val+
                                       "<font color=#A52A2A> (case difference only)</font>"+
                                       "</td>");
                      }
                      hasData=true;
                 }
             }       

              writer.println("            </tr>\n");
        }
  
        writer.println( "        </table>\n");
        
        if(!hasData){
            writer.println( "       <p><font size=16 color=#FF0000> Data exists only in ICU </font></p>\n");
        } 
        writer.println("        <p>Created on: " + cal.getTime() +"</p>\n"+
                            "    </body>\n"+
                            "</html>");
        writer.flush();
    }


    /**
     * Compare two files by parsing into DOMs and comparing trees.
     * @param goldFileName expected file
     * @param testFileName actual file
     * @param reporter PrintWriter to dump status info to
     * @param array of warning flags (for whitespace diffs, I think?)
     * NEEDSDOC @param warning
     * @param attributes to attempt to set onto parsers
     * @return true if they match, false otherwise
     */
    private Document goldDoc=null;
    
    public boolean compare(String goldFileName, String goldKey, 
                           String testFileName, String testKey, boolean mergeData)
    {
        
        String temp= goldFileName;
        // parse the gold doc only if it is null
        if(goldDoc==null){
            goldDoc = parse(goldFileName);
            
            if((goldKey.indexOf("icu")>=0 ) || (goldKey.indexOf("jdk")>=0)){
                // OK we have a posix style locale data
                // merge all data in inheritence tree into goldDoc
                int index = -1;
                while((index = temp.indexOf("_")) >0 && index > goldFileName.lastIndexOf("\\")){
                    Document parentDoc = parse((temp = temp.substring(0,index)+".xml"));
                    if(parentDoc!=null){
                       mergeElements(goldDoc.getDocumentElement(),parentDoc.getDocumentElement());
                    }
                }
            }
        }

        // parse the test doc only if gold doc was parsed OK
        Document testDoc = (null != goldDoc)
                           ? parse(testFileName) : null;
                           
        if(((testKey.indexOf("icu")>=0) || (testKey.indexOf("jdk")>=0)) && testDoc!=null){
            // OK we have a posix style locale data in goldDoc
            // merge all data in inheritence tree into testDoc
            temp=testFileName;
            int index = -1;
            while((index = temp.indexOf("_")) >0 && index > testFileName.lastIndexOf("\\")){
                    Document parentDoc = parse((temp = temp.substring(0,index)+".xml"));
                    if(parentDoc!=null){
                       mergeElements(testDoc.getDocumentElement(),parentDoc.getDocumentElement());
                    }
             }
        
        }
        
        if (null == goldDoc)
        {
            doesNotExist.add(goldKey);
            return false;
        }
        else if (null == testDoc)
        {
            doesNotExist.add(testKey);
            return false;
        }
        if(mergeData){
            return extractMergeData(goldDoc,goldKey,testDoc,testKey);
        }else{   
            return compareElementsAndData(goldDoc,goldKey,testDoc,testKey);
        }
    }
    boolean canonical  = false;
    
    String  encoding   = "UTF-8"; // default encoding
    
    /** Returns a sorted list of attributes. */
    protected Attr[] sortAttributes(NamedNodeMap attrs) {

        int len = (attrs != null) ? attrs.getLength() : 0;
        Attr array[] = new Attr[len];
        for ( int i = 0; i < len; i++ ) {
            array[i] = (Attr)attrs.item(i);
        }
        for ( int i = 0; i < len - 1; i++ ) {
            String name  = array[i].getNodeName();
            int    index = i;
            for ( int j = i + 1; j < len; j++ ) {
                String curName = array[j].getNodeName();
                if ( curName.compareTo(name) < 0 ) {
                    name  = curName;
                    index = j;
                }
            }
            if ( index != i ) {
                Attr temp    = array[i];
                array[i]     = array[index];
                array[index] = temp;
            }
        }

        return(array);

    } // sortAttributes(NamedNodeMap):Attr[]
    
        /** Normalizes the given string. */
    protected String normalize(String s) {
        StringBuffer str = new StringBuffer();

        int len = (s != null) ? s.length() : 0;
        for ( int i = 0; i < len; i++ ) {
            char ch = s.charAt(i);
            switch ( ch ) {
            case '<': {
                    str.append("&lt;");
                    break;
                }
            case '>': {
                    str.append("&gt;");
                    break;
                }
            case '&': {
                    str.append("&amp;");
                    break;
                }
            case '"': {
                    str.append("&quot;");
                    break;
                }
            case '\'': {
                    str.append("&apos;");
                    break;
                }
            case '\r':
            case '\n': {
                    if ( canonical ) {
                        str.append("&#");
                        str.append(Integer.toString(ch));
                        str.append(';');
                        break;
                    }
                    // else, default append char
                }
            default: {
                    str.append(ch);
                }
            }
        }

        return(str.toString());

    } // normalize(String):String


    /** Prints the specified node, recursively. */
    public void print(PrintWriter out, Node node) {

        // is there anything to do?
        if ( node == null ) {
            return;
        }

        int type = node.getNodeType();
        
        switch ( type ) {
        // print document
        case Node.DOCUMENT_NODE: {
               if ( !canonical ) {
                    out.println("<?xml version=\"1.0\" encoding=\""+
                                encoding + "\"?>");
                }
                //print(((Document)node).getDocumentElement());

                NodeList children = node.getChildNodes();
                for ( int iChild = 0; iChild < children.getLength(); iChild++ ) {
                    print(out,children.item(iChild));
                }
                out.flush();
                break;
            }

            // print element with attributes
        case Node.ELEMENT_NODE: {
                out.print('<');
                out.print(node.getNodeName());
                Attr attrs[] = sortAttributes(node.getAttributes());
                for ( int i = 0; i < attrs.length; i++ ) {
                    Attr attr = attrs[i];
                    out.print(' ');
                    out.print(attr.getNodeName());
                    out.print("=\"");
                    out.print(normalize(attr.getNodeValue()));
                    out.print('"');
                }
                out.print('>');
                NodeList children = node.getChildNodes();
                if ( children != null ) {
                    int len = children.getLength();
                    for ( int i = 0; i < len; i++ ) {
                        print(out,children.item(i));
                    }
                }
                break;
            }

            // handle entity reference nodes
        case Node.ENTITY_REFERENCE_NODE: {
                if ( canonical ) {
                    NodeList children = node.getChildNodes();
                    if ( children != null ) {
                        int len = children.getLength();
                        for ( int i = 0; i < len; i++ ) {
                            print(out,children.item(i));
                        }
                    }
                } else {
                    out.print('&');
                    out.print(node.getNodeName());
                    out.print(';');
                }
                break;
            }

            // print cdata sections
        case Node.CDATA_SECTION_NODE: {
                if ( canonical ) {
                    out.print(normalize(node.getNodeValue()));
                } else {
                    out.print("<![CDATA[");
                    out.print(node.getNodeValue());
                    out.print("]]>");
                }
                break;
            }

            // print text
        case Node.TEXT_NODE: {
                out.print(normalize(node.getNodeValue()));
                break;
            }

            // print processing instruction
        case Node.PROCESSING_INSTRUCTION_NODE: {
                out.print("<?");
                out.print(node.getNodeName());
                String data = node.getNodeValue();
                if ( data != null && data.length() > 0 ) {
                    out.print(' ');
                    out.print(data);
                }
                out.println("?>");
                break;
            }
        }

        if ( type == Node.ELEMENT_NODE ) {
            out.print("</");
            out.print(node.getNodeName());
            out.print('>');
        }

        out.flush();
    } // print(Node)
    
    // Reporter format:
    // REASON_CONSTANT;gold val;test val;reason description
    private void addNodeValue(NodeList list,String nodeName,String nodeValue,String caseDiff){
        for(int i=0;i<list.getLength();i++){
            Node node = list.item(i);
            if(nodeName.equals(node.getNodeName())){   
                node.getFirstChild().setNodeValue(nodeValue);
                if(caseDiff!=null){
	                NamedNodeMap attr = node.getAttributes();
	                Node case_diff = attr.getNamedItem("case_diff");
	                case_diff.setNodeValue(caseDiff);
                }
            }
        }
    }
    private void addElement(String parentNode, String childNode, String attr,
                               String nodeName1,  String value1,
                               String nodeName2, String value2){
            String id ;
            String caseDiff=null;
            if(Normalizer.compare(value1,value2,0)!=0){
                //System.out.println("Value1: "+value1+ "  Value2: "+ value2);
	            if(Normalizer.compare(value1,value2,Normalizer.COMPARE_IGNORE_CASE)==0){
	                caseDiff="true";
	            }
            }
            if(attr!=null){
                id = parentNode+"_"+childNode+"_"+attr;
            }else{
                id = parentNode+"_"+childNode;
            }
                
            Element element = resultDocument.getElementById(id);
            NodeList nodes=null;
            NamedNodeMap attribMap=null;
            Node rootNode =resultDocument.getElementsByTagName("difference_xml").item(0);
            if(element!=null){
                nodes = element.getChildNodes();
                attribMap=element.getAttributes();              
            }else{
               NodeList nodeList=resultDocument.getElementsByTagName("difference_element");
               // the first node is always the empty one in the result document
               // so get that node and clone it
               Node node = nodeList.item(0).cloneNode(true);
               attribMap=node.getAttributes();
               nodes= node.getChildNodes();
            }
            addNodeValue(nodes,nodeName1,value1,(nodeName1.equals(goldKey))?null:caseDiff);
            addNodeValue(nodes,nodeName2,value2,(nodeName2.equals(goldKey))?null:caseDiff);
            Node parent_node = attribMap.getNamedItem("parent_node");
            Node node_name   = attribMap.getNamedItem("node_name");
            Node id_attrib   = attribMap.getNamedItem("id");
            Node index       = attribMap.getNamedItem("index");
            parent_node.setNodeValue(parentNode);
            node_name.setNodeValue(childNode);
            id_attrib.setNodeValue(id);
            index.setNodeValue((attr==null) ? "&nbsp;" : attr);
            rootNode.appendChild(nodes.item(0).getParentNode());       
    }
    private void addDifference(String parentNode, String childNode, String attr,
                               String nodeName1,  String value1,
                               String nodeName2, String value2){
            String id ;
            // Decompose the values and find out if they are equal
            if(Normalizer.compare(value1,value2,0)==0){
                // the values are equal just return
                return;
            }
            String caseDiff= null;
            if(Normalizer.compare(value1,value2,Normalizer.COMPARE_IGNORE_CASE)==0){
                caseDiff="true";
            }
            if(attr!=null){
                id = parentNode+"_"+childNode+"_"+attr;
            }else{
                id = parentNode+"_"+childNode;
            }
                
            Element element = resultDocument.getElementById(id);
            NodeList nodes=null;
            NamedNodeMap attribMap=null;
            Node rootNode =resultDocument.getElementsByTagName("difference_xml").item(0);
            if(element!=null){
                nodes = element.getChildNodes();
                attribMap=element.getAttributes();              
            }else{
               NodeList nodeList=resultDocument.getElementsByTagName("difference_element");
               // the first node is always the empty one in the result document
               // so get that node and clone it
               Node node = nodeList.item(0).cloneNode(true);
               attribMap=node.getAttributes();
               nodes= node.getChildNodes();
            }
            addNodeValue(nodes,nodeName1,value1,caseDiff);
            addNodeValue(nodes,nodeName2,value2,caseDiff);
            Node parent_node = attribMap.getNamedItem("parent_node");
            Node node_name   = attribMap.getNamedItem("node_name");
            Node id_attrib   = attribMap.getNamedItem("id");
            Node index       = attribMap.getNamedItem("index");
            parent_node.setNodeValue(parentNode);
            node_name.setNodeValue(childNode);
            id_attrib.setNodeValue(id);
            index.setNodeValue((attr==null) ? "&nbsp;" : attr);
            rootNode.appendChild(nodes.item(0).getParentNode());
            
            
            
    }
    
    // ---------------------------------------------------------------------------
    //
    //   Merge element nodes.  dest and source are Element nodes of the same type.
    //                         Move any children Elements that exist in the source but not in the
    //                         destination into the destination
    //
    // ---------------------------------------------------------------------------
    private void  mergeElements(Node dest, Node source) {
        Node   childOfSource;
        Node   childOfDest;
        
        Document destDoc = dest.getOwnerDocument();
        Node spaces = destDoc.createTextNode("\n       ");
        
        for (childOfSource = source.getFirstChild(); childOfSource != null; childOfSource = childOfSource.getNextSibling()) {
            if (childOfSource.getNodeType() != Node.ELEMENT_NODE) {
                continue;
            }
            if(childOfSource.getNodeName().equals("collation") 
                || childOfSource.getNodeName().equals("timeZoneNames")
                ){
                continue;
            }
            boolean didMerge = false;
            for (childOfDest = dest.getFirstChild(); childOfDest != null; childOfDest = childOfDest.getNextSibling()) {
                if (childOfDest.getNodeType() == Node.ELEMENT_NODE  &&
                       childOfDest.getNodeName().equals(childOfSource.getNodeName())) {
                    // The destination document already has an element of this type at this level.
                    //   Recurse to pick up any extra children that the source node may have.
                    mergeElements(childOfDest, childOfSource);
                    didMerge = true;
                    break;
                }
            }
    
            if (didMerge == false) {
                // destination document had no corresponding node to the current childOfSource.  Add it.
                Node importedNode = destDoc.importNode(childOfSource, true);
                dest.appendChild(spaces);
                dest.appendChild(importedNode);
            }
        }
        //dest.appendChild(spaces);
        
    }
    
    double args1  = 10000000000.00;
    double args2  = -10000000000.00;
    
    DecimalFormat fmt = new DecimalFormat(); 
    
    private boolean comparePatterns(String pat1,String pat2){
        fmt.applyPattern(pat1);
        String s1 = fmt.format(args1);
        String s3 = fmt.format(args2);
        fmt.applyPattern(pat2);
        String s2 = fmt.format(args1);
        String s4 = fmt.format(args2);
        if(s1.equals(s2) && s3.equals(s4)){
            return true;
        }
        return false;
    }
    private boolean compareElementsAndData(Node goldNode,String goldKey,
                                           Document testDoc,String testKey){
    
        Node childOfSource;

        for(childOfSource = goldNode.getFirstChild(); childOfSource != null; childOfSource = childOfSource.getNextSibling()) {
            if (childOfSource.getNodeType() != Node.ELEMENT_NODE) {
                continue;
            }
            if(childOfSource.getNodeName().equals("collation") 
                || childOfSource.getNodeName().equals("timeZoneNames")
                || childOfSource.getNodeName().equals("versioning")){
                continue;
            }
            NamedNodeMap attr = childOfSource.getAttributes();       
            NodeList destList = testDoc.getElementsByTagName(childOfSource.getNodeName());
            Node sourceID = attr.getNamedItem("id");
           
    
            for(int i =0 ; i<destList.getLength(); i++){
                Node destNode =destList.item(i);
                NamedNodeMap destAttr = destNode.getAttributes();
                /* get the source and destination nodes with attribute id */
                Node destID = destAttr.getNamedItem("id");
                if(destID!=null && sourceID!=null){
                    String sourceVal =sourceID.getNodeValue();
                    String destVal = destID.getNodeValue();
                    
                    if(sourceVal.equals(destVal)){
                        //System.out.println(sourceVal);
                        //System.out.println(destVal);
                        if(destNode.hasChildNodes() && childOfSource.hasChildNodes()){
                            if(destNode.getParentNode().getNodeName().equals(childOfSource.getParentNode().getNodeName())){
                                String destNodeVal = trim(destNode.getFirstChild().getNodeValue());
                                String sourceNodeVal = trim(childOfSource.getFirstChild().getNodeValue());

                                //System.out.println(childOfSource.getFirstChild().getNodeName());
                                //System.out.println(destNode.getFirstChild().getNodeName());
                                if(!destNodeVal.equals(sourceNodeVal)){
                                    boolean write = true;
                                    String parentNodeName = trim(childOfSource.getParentNode().getNodeName());
                                    String childNodeName  = trim(childOfSource.getNodeName());
                                    if(childNodeName.equals("pattern")){
                                        if(comparePatterns(sourceNodeVal,destNodeVal)){
                                            write = false;
                                        }
                                    }
                                    if(write){
                                        addDifference(parentNodeName,
                                                      childNodeName,
                                                      destVal,
                                                      testKey,
                                                      destNodeVal,
                                                      goldKey,
                                                      sourceNodeVal);
                                    }
    
                                }
                            }
                        }
                    }
                }else{
                    if(destNode.getNodeName().equals(childOfSource.getNodeName())&&
                        destNode.getParentNode().getNodeName().equals(childOfSource.getParentNode().getNodeName())
                       ){
                        if(destNode.hasChildNodes() && childOfSource.hasChildNodes()){
    
                            String destNodeVal = trim(destNode.getFirstChild().getNodeValue());
                            String sourceNodeVal = trim(childOfSource.getFirstChild().getNodeValue());
    
                            String attID = null;
                            if(!destNodeVal.equals(sourceNodeVal)){
                                boolean write = true;
                                String parentNodeName = childOfSource.getParentNode().getNodeName();
                                String childNodeName  = childOfSource.getNodeName();
                                if(childNodeName.equals("pattern")){
                                        if(comparePatterns(sourceNodeVal,destNodeVal)){
                                            write = false;
                                        }
                                }
                                if(write){
                                    addDifference(parentNodeName,
                                                  childNodeName,
                                                  attID,
                                                  testKey,
                                                  destNodeVal,
                                                  goldKey,
                                                  sourceNodeVal);
                                }
                            }
                        }
                    }
                
                }
            }
      
            compareElementsAndData(childOfSource,goldKey,testDoc,testKey);
        }
       return true;
    }    
    private String trim(String source){
        char[] src = source.toCharArray();
        char[] dest = new char[src.length];

        int start=0;
        while(start<(src.length) && (UCharacter.isWhitespace(src[start])|| src[start]==0xA0)){start++;}
        int stop=src.length-1;
        while(stop>0 && (UCharacter.isWhitespace(src[stop])||(src[stop]==0xA0))){stop--;}
        if(stop!=-1 && start!=src.length){
	        System.arraycopy(src,start,dest,0,(stop-start)+1);
	        return new String(dest,0,(stop-start)+1);
        }else{
            return new String();
        }
      
    }
    private boolean extractMergeData(Node goldNode,String goldKey,
                                           Document testDoc,String testKey){
    
        Node childOfSource;

        for(childOfSource = goldNode.getFirstChild(); childOfSource != null; childOfSource = childOfSource.getNextSibling()) {
            if (childOfSource.getNodeType() != Node.ELEMENT_NODE) {
                continue;
            }
            if(childOfSource.getNodeName().equals("collation") 
                || childOfSource.getNodeName().equals("timeZoneNames")
                || childOfSource.getNodeName().equals("versioning")){
                continue;
            }
            NamedNodeMap attr = childOfSource.getAttributes();       
            NodeList destList = testDoc.getElementsByTagName(childOfSource.getNodeName());
            Node sourceID = attr.getNamedItem("id");
    
            for(int i =0 ; i<destList.getLength(); i++){
                Node destNode =destList.item(i);
                NamedNodeMap destAttr = destNode.getAttributes();
                /* get the source and destination nodes with attribute id */
                Node destID = destAttr.getNamedItem("id");
                if(destID!=null && sourceID!=null){
                    String sourceIDVal =sourceID.getNodeValue();
                    String destIDVal = destID.getNodeValue();
                    
                    if(sourceIDVal.equals(destIDVal)){
                        //System.out.println(sourceVal);
                        //System.out.println(destVal);
                        if(destNode.hasChildNodes() && childOfSource.hasChildNodes()){
                            if(destNode.getParentNode().getNodeName().equals(childOfSource.getParentNode().getNodeName())){
                                String destNodeVal = trim(destNode.getFirstChild().getNodeValue());
                                String sourceNodeVal = trim(childOfSource.getFirstChild().getNodeValue());
                                String parentNodeName = trim(childOfSource.getParentNode().getNodeName());
                                String childNodeName  = trim(childOfSource.getNodeName());
                                if(sourceNodeVal.length()!=0){
                                    addElement(parentNodeName,
                                                      childNodeName,
                                                      destIDVal,
                                                      testKey,
                                                      destNodeVal,
                                                      goldKey,
                                                      sourceNodeVal);
                                }
                                //System.out.println(childOfSource.getFirstChild().getNodeName());
                                //System.out.println(destNode.getFirstChild().getNodeName());
                            }
                        }
                    }
                }else{
                    if(destNode.getNodeName().equals(childOfSource.getNodeName())&&
                        destNode.getParentNode().getNodeName().equals(childOfSource.getParentNode().getNodeName())
                       ){
                        if(destNode.hasChildNodes() && childOfSource.hasChildNodes()){
    
                            String destNodeVal = trim(destNode.getFirstChild().getNodeValue());
                            String sourceNodeVal = trim(childOfSource.getFirstChild().getNodeValue());
    
                            String parentNodeName = trim(childOfSource.getParentNode().getNodeName());
                            String childNodeName  = trim(childOfSource.getNodeName());
                            if(sourceNodeVal.length()!=0){
                                addElement(parentNodeName,
                                                  childNodeName,
                                                  null,
                                                  testKey,
                                                  destNodeVal,
                                                  goldKey,
                                                  sourceNodeVal);
                            }
                        }
                    }
                
                }
            }
      
            extractMergeData(childOfSource,goldKey,testDoc,testKey);
        }
       return true;
    } 

    /**
     * Utility method to translate a String filename to URL.  
     *
     * Note: This method is not necessarily proven to get the 
     * correct URL for every possible kind of filename; it should 
     * be improved.  It handles the most common cases that we've 
     * encountered when running Conformance tests on Xalan.
     * Also note, this method does not handle other non-file:
     * flavors of URLs at all.
     *
     * If the name is null, return null.
     * If the name starts with a common URI scheme (namely the ones 
     * found in the examples of RFC2396), then simply return the 
     * name as-is (the assumption is that it's already a URL)
     * Otherwise we attempt (cheaply) to convert to a file:/// URL.
     * 
     * @param String local path\filename of a file
     * @return a file:/// URL, the same string if it appears to 
     * already be a URL, or null if error
     */
    public static String filenameToURL(String filename)
    {
        // null begets null - something like the commutative property
        if (null == filename)
            return null;

        // Don't translate a string that already looks like a URL
        if (filename.startsWith("file:")
            || filename.startsWith("http:")
            || filename.startsWith("ftp:")
            || filename.startsWith("gopher:")
            || filename.startsWith("mailto:")
            || filename.startsWith("news:")
            || filename.startsWith("telnet:")
           )
            return filename;

        File f = new File(filename);
        String tmp = null;
        try
        {
            // This normally gives a better path
            tmp = f.getCanonicalPath();
        }
        catch (IOException ioe)
        {
            // But this can be used as a backup, for cases 
            //  where the file does not exist, etc.
            tmp = f.getAbsolutePath();
        }

        // URLs must explicitly use only forward slashes
        if (File.separatorChar == '\\') {
            tmp = tmp.replace('\\', '/');
        }
        // Note the presumption that it's a file reference
        // Ensure we have the correct number of slashes at the 
        //  start: we always want 3 /// if it's absolute
        //  (which we should have forced above)
        if (tmp.startsWith("/"))
            return "file://" + tmp;
        else
            return "file:///" + tmp;

    }


    /**
     * Simple worker method to parse filename to a Document.  
     *
     * Attempts XML parse, then HTML parse (when parser available), 
     * then just parses as text and sticks into a text node.
     *
     * @param filename to parse as a local path
     * @param attributes name=value pairs to set on the 
     * DocumentBuilderFactory that we use to parse
     *
     * @return Document object with contents of the file; 
     * otherwise throws an unchecked RuntimeException if there 
     * is any fatal problem
     */
    Document parse(String filename)
    {
        // Force filerefs to be URI's if needed: note this is independent of any other files
        String docURI = filenameToURL(filename);
        return parse(new InputSource(docURI),filename);
    }
    
    Document parse(InputSource docSrc, String filename){
        
        DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
        // Always set namespaces on
        dfactory.setNamespaceAware(true);
        // Set other attributes here as needed
        //applyAttributes(dfactory, attributes);
        
        // Local class: cheap non-printing ErrorHandler
        // This is used to suppress validation warnings
        ErrorHandler nullHandler = new ErrorHandler() {
            public void warning(SAXParseException e) throws SAXException {}
            public void error(SAXParseException e) throws SAXException {}
            public void fatalError(SAXParseException e) throws SAXException 
            {
                throw e;
            }
        };

        Document doc = null;
        try
        {
            // First, attempt to parse as XML (preferred)...
            DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
            docBuilder.setErrorHandler(nullHandler);
            doc = docBuilder.parse(docSrc);
        }
        catch (Throwable se)
        {
            // ... if we couldn't parse as XML, attempt parse as HTML...
            System.out.println("ERROR :" + se.toString());
            try
            {
                // @todo need to find an HTML to DOM parser we can use!!!
                // doc = someHTMLParser.parse(new InputSource(filename));
                throw new RuntimeException("XMLComparator no HTML parser!");
            }
            catch (Exception e)
            {
                if(filename!=null)
                {
                    // ... if we can't parse as HTML, then just parse the text
                    try
                    {
    
                        // Parse as text, line by line
                        //   Since we already know it should be text, this should 
                        //   work better than parsing by bytes.
                        FileReader fr = new FileReader(filename);
                        BufferedReader br = new BufferedReader(fr);
                        StringBuffer buffer = new StringBuffer();
                        for (;;)
                        {
                            String tmp = br.readLine();
    
                            if (tmp == null)
                            {
                                break;
                            }
    
                            buffer.append(tmp);
                            buffer.append("\n");  // Put in the newlines as well
                        }
    
                        DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
                        doc = docBuilder.newDocument();
                        Element outElem = doc.createElement("out");
                        Text textNode = doc.createTextNode(buffer.toString());
    
                        // Note: will this always be a valid node?  If we're parsing 
                        //    in as text, will there ever be cases where the diff that's 
                        //    done later on will fail becuase some really garbage-like 
                        //    text has been put into a node?
                        outElem.appendChild(textNode);
                        doc.appendChild(outElem);
                    }
                    catch (Throwable throwable)
                    {

                        //throwable.printStackTrace();
                    }
                }
            }
        }
        return doc;
    }  // end of parse()
}
