// © 2017 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 **********************************************************************
 * Copyright (C) 2016 and later: Unicode, Inc. and others.
 * Copyright (c) 2006-2013, International Business Machines
 * Corporation and others.  All Rights Reserved.
 **********************************************************************
 * Created on 2006-7-24 ?
 * Moved from Java 1.4 to 1.5? API by srl 2009-01-16
 */
package com.ibm.icu.dev.tools.docs;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.*;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;


/**
 A utility to report the status change between two ICU releases

To use the utility
1. Generate the XML files
    (put the two ICU releases on your machine ^_^ )
    (generate 'Doxygen' file on Windows platform with Cygwin's help)
    Edit the generated 'Doxygen' file under ICU4C source directory
    a) GENERATE_XML           = YES
    b) Sync the ALIASES definiation
       (For example, copy the ALIASES defination from ICU 3.6
       Doxygen file to ICU 3.4 Doxygen file.)
    c) gerenate the XML files
2. Build the tool
    Download Apache Xerces Java Parser
    Build this file with the library
3. Edit the api-report-config.xml file & Change the file according your real configuration
4. Run the tool to generate the report.

 * @author Raymond Yang
 */
public class StableAPI {

    private static final String DOC_FOLDER = "docFolder";
	private static final String INDEX_XML = "index.xml";
	private static final String ICU_SPACE_PREFIX = "ICU ";
	private static final String INITIALIZER_XPATH = "initializer";
	private static final String NAME_XPATH = "name";
	private static final String UVERSIONA = "uvernum_8h.xml";
	private static final String UVERSIONB = "uversion_8h.xml";
    private static final String U_ICU_VERSION = "U_ICU_VERSION";
    /* ICU 4.4+ */
	private static final String ICU_VERSION_XPATHA = "/doxygen/compounddef[@id='uvernum_8h'][@kind='file']/sectiondef[@kind='define']";
	/* ICU <4.4 */
	private static final String ICU_VERSION_XPATHB = "/doxygen/compounddef[@id='uversion_8h'][@kind='file']/sectiondef[@kind='define']";
    private static String ICU_VERSION_XPATH = ICU_VERSION_XPATHA;

	private String leftVer;
    private File leftDir = null;
//    private String leftStatus;
    private String leftMilestone = "";

    private String rightVer;
    private File rightDir = null;
//    private String rightStatus;
    private String rightMilestone = "";

    private InputStream dumpCppXsltStream = null;
	private InputStream dumpCXsltStream = null;
	private InputStream reportXslStream = null;
	private static final String CXSLT = "dumpAllCFunc.xslt";
	private static final String CPPXSLT = "dumpAllCppFunc.xslt";
	private static final String RPTXSLT = "genReport.xslt";

    private File dumpCppXslt;
    private File dumpCXslt;
    private File reportXsl;
    private File resultFile;


    static Map<String,Set<String>> simplifications = new TreeMap<String,Set<String>>();

    static void addSimplification(String prototype0, String prototype) {
        Set<String> s = simplifications.get(prototype);
        if(s==null) {
            s = new TreeSet<String>();
            simplifications.put(prototype, s);
        }
        s.add(prototype0);
    }

    static Set<String> getChangedSimplifications() {
        Set<String> output = new TreeSet<String>();
        for(Map.Entry<String,Set<String>> e : simplifications.entrySet()) {
            if(e.getValue().size()>1) {
                output.add(e.getKey());
            }
        }
        return output;
    }


    final private static String notFound = "(missing)";

    public static void main(String[] args) throws TransformerException, ParserConfigurationException, SAXException, IOException, XPathExpressionException {

        StableAPI t = new StableAPI();
        t.run(args);
    }

    private void run(String[] args) throws XPathExpressionException, TransformerException, ParserConfigurationException, SAXException, IOException {
        this.parseArgs(args);
        Set<JoinedFunction> full = new TreeSet<JoinedFunction>();

        System.err.println("Reading C++...");
        Set<JoinedFunction> setCpp = this.getFullList(dumpCppXsltStream, dumpCppXslt.getName());
        full.addAll(setCpp);
        System.out.println("read "+setCpp.size() +" C++.  Reading C:");

        Set<JoinedFunction> setC = this.getFullList(dumpCXsltStream, dumpCXslt.getName());
        full.addAll(setC);

        System.out.println("read "+setC.size() +" C. Setting node:");

        Node fullList = this.setToNode(full);
//        t.dumpNode(fullList,"");

        System.out.println("Node set. Reporting:");

        this.reportSelectedFun(fullList);
        System.out.println("Done. Please check " + this.resultFile);

        Set<String> changedSimp = getChangedSimplifications();
        if(!changedSimp.isEmpty()) {
            System.out.println("--- changed simplifications ---");
            for(String k : changedSimp) {
                System.out.println(k);
                for(String s : simplifications.get(k)) {
                    System.out.println("\t"+s);
                }
            }
        }
    }


    private void parseArgs(String[] args){
        for (int i = 0; i < args.length; i++) {
            String arg = args[i];
            if (arg == null || arg.length() == 0) {
                continue;
            }
            if (arg.equals("--help") ) {
                printUsage();
            } else if (arg.equals("--oldver") ) {
                leftVer = args[++i];
            } else if (arg.equals("--olddir") ) {
                leftDir = new File(args[++i]);
            } else if (arg.equals("--newver")) {
                rightVer = args[++i];
            } else if (arg.equals("--newdir")) {
                rightDir = new File(args[++i]);
            } else if (arg.equals("--cxslt") ) {
                dumpCXslt = new File(args[++i]);
            } else if (arg.equals("--cppxslt") ) {
                dumpCppXslt = new File(args[++i]);
            } else if (arg.equals("--reportxslt") ) {
                reportXsl = new File(args[++i]);
            } else if (arg.equals("--resultfile")) {
                resultFile = new File(args[++i]);
            } else {
                System.out.println("Unknown option: "+arg);
               printUsage();
            }
        }

        dumpCppXsltStream = loadStream(CPPXSLT, "--cppxslt", dumpCppXslt);
        dumpCXsltStream= loadStream(CXSLT, "--cxslt", dumpCXslt);
        reportXslStream= loadStream(RPTXSLT, "--reportxslt", reportXsl);

        leftVer = trimICU(setVer(leftVer, "old", leftDir));
        rightVer = trimICU(setVer(rightVer, "new", rightDir));
    }


    @SuppressWarnings("resource")
	private InputStream loadStream(String name, String argName, File argFile) {
    	InputStream stream = null;
    	if(argFile != null) {
    		try {
                stream = new FileInputStream(argFile);
                System.out.println("Loaded file " + argFile.getName());
	    	} catch (IOException ioe) {
	    		throw new RuntimeException("Error: Could not load " + argName +" " + argFile.getPath() + " - " + ioe.toString(), ioe);
	    	}
    	} else {
        	stream = StableAPI.class.getResourceAsStream(name);
        	if(stream == null) {
        		throw new InternalError("No resource found for " + StableAPI.class.getPackage().getName()+"/"+ name + " -   use " + argName);
        	} else {
        		System.out.println("Loaded resource " + name);
        	}
        }
        return stream;
	}

    private static Set<String> warnSet = new TreeSet<String>();

    private static void warn(String what) {
        if(!warnSet.contains(what)) {
               System.out.println("Warning: "+what);
               if(warnSet.isEmpty()) {
                      System.out.println(" (These warnings are only printed one time each.)");
               }
               warnSet.add(what);
        }
    }

    private static boolean didWarnSuperTrim = false;

    private static String trimICU(String ver) {
        Matcher icuVersionMatcher =  Pattern.compile("ICU *\\d+(\\.\\d+){0,2}").matcher(ver);
        if (icuVersionMatcher.find()) {
            return icuVersionMatcher.group();
        } else {
            warn("@whatever not followed by ICU <version number>");
            return "";
        }
    }

    private String setVer(String prevVer, String whichVer, File dir) {
	    String UVERSION = UVERSIONA;
    	if(dir==null) {
    		System.out.println("--"+whichVer+"dir not set.");
    		printUsage(); /* exits */
    	} else if(!dir.exists()||!dir.isDirectory()) {
    		System.out.println("--"+whichVer+"dir="+dir.getName()+" does not exist or is not a directory.");
    		printUsage(); /* exits */
    	}
        String result = null;
        // looking for: <name>U_ICU_VERSION</name> in uversion_8h.xml:        <initializer>&quot;3.8.1&quot;</initializer>
        try {
            File verFile = new File(dir, UVERSION);
		    if(!verFile.exists()) {
				UVERSION=UVERSIONB;
				ICU_VERSION_XPATH=ICU_VERSION_XPATHB;
				verFile = new File(dir, UVERSION);
		    } else {
				ICU_VERSION_XPATH=ICU_VERSION_XPATHA;
		    }
            Document doc = getDocument(verFile);
            DOMSource uvernum_h = new DOMSource(doc);
            XPath xpath = XPathFactory.newInstance().newXPath();

            Node defines = (Node)xpath.evaluate(ICU_VERSION_XPATH, uvernum_h.getNode(), XPathConstants.NODE);

	    if(defines==null) {
	    	System.err.println("can't load from "+verFile.getName()+":"+ICU_VERSION_XPATH);
	    }

            NodeList nList = defines.getChildNodes();
            for (int i = 0; result==null&& (i < nList.getLength()); i++) {
                Node ln = nList.item(i);
                if(!"memberdef".equals(ln.getNodeName())) {
                    continue;
                }
                Node name = (Node)xpath.evaluate(NAME_XPATH, ln, XPathConstants.NODE);
                if(name==null) continue;

               // System.err.println("Gotta node: " + name);

                Node nameVal = name.getFirstChild();
                if(nameVal==null) nameVal = name;

                String nameStr = nameVal.getNodeValue();
                if(nameStr==null) continue;

               // System.err.println("Gotta name: " + nameStr);

                if(nameStr.trim().equals(U_ICU_VERSION)) {
                    Node initializer = (Node)xpath.evaluate(INITIALIZER_XPATH, ln, XPathConstants.NODE);
                    if(initializer==null) System.err.println("initializer with no value");
                    Node initVal = initializer.getFirstChild();
//                    if(initVal==null) initVal = initializer;
                    String initStr = initVal.getNodeValue().trim().replaceAll("\"","");
                    result = ICU_SPACE_PREFIX+initStr;
                    System.err.println("Detected "+whichVer + " version: " + result);

                    String milestoneOf = "";

                    // TODO:  #1 use UVersionInfo. (this tool doesn't depend on ICU4J yet)
                    //        #2 move this to a utility function: strip/"explain" an ICU version #.
                    if(result.startsWith("ICU ")) {
                        String vers[] = result.substring(4).split("\\.");
                        int maj = Integer.parseInt(vers[0]);
                        int min = vers.length>1?Integer.parseInt(vers[1]):0;
                        int micr = vers.length>2?Integer.parseInt(vers[2]):0;
                        int patch = vers.length>3?Integer.parseInt(vers[3]):0;
                        System.err.println(" == ["+vers.toString()+"] " + maj + " . " + min + " . " + micr + " . " + patch );
                        if(maj >= 49) {
                            // new scheme: 49 and following.
                            String truncVersion = "ICU " +maj;
                            if(min == 0) {
                                milestoneOf = " (m"+micr+")";
                                System.err.println("    .. " + milestoneOf + " is a milestone towards " + truncVersion);
                            } else if(min == 1) {
                                // Don't denote as milestone
                                result = "ICU "+(maj);
                                System.err.println("    .. " + milestoneOf + " is the release of " + truncVersion);
                            } else {
                                milestoneOf = " (update #"+(min-1)+": "+result.substring(4)+")";
                                result = "ICU "+(maj);
                                System.err.println("    .. " + milestoneOf + " is an update to  " + truncVersion);
                            }
                            // always truncate to major # for comparing tags.
                            result = truncVersion;
                        } else {
                            // old scheme - 1.0.* .. 4.8.*
                            String truncVersion = "ICU " + maj+"."+min;
                            if((min%2)==1) {
                                milestoneOf = " ("+maj+"."+(min+1)+"m"+micr+")";
                                truncVersion = "ICU "+(maj)+"."+(min+1);
                                System.err.println("    .. " + milestoneOf + " is a milestone towards " + truncVersion);
                            } else if(micr==0 && patch==0) {
                                System.err.println("    .. " + milestoneOf + " is the release of " + truncVersion);
                            } else {
                                milestoneOf = " (update "+micr+"."+patch+")";
                                System.err.println("    .. " + milestoneOf + " is an update to " + truncVersion);
                            }
                            result = truncVersion;
                        }
                        if(whichVer.equals("new")) {
                            rightMilestone = milestoneOf;
                        } else {
                            leftMilestone = milestoneOf;
                        }
                    }
                }

            }
            //dumpNode(defines,"");
        } catch(Throwable t) {
            t.printStackTrace();
            System.err.println("Warning: Couldn't get " + whichVer+  " version from "+ UVERSION + " - reverting to " + prevVer);
            result = prevVer;
        }

        if(result != null) {

        }

        if(prevVer != null) {
            if(result != null) {
                if(!result.equals(prevVer)) {
                    System.err.println("Note: Detected " + result + " version but we'll use your requested --"+whichVer+"ver "+prevVer);
                    result = prevVer;
                    if(!rightMilestone.isEmpty()&&whichVer.equals("new")) {
                        System.err.println(" .. ignoring milestone indicator " + rightMilestone);
                        rightMilestone = "";
                    }
                    if(!leftMilestone.isEmpty()&&!whichVer.equals("new")) {
                        leftMilestone="";
                    }
                } else {
                    System.err.println("Note: You don't need to use  '--"+whichVer+"ver "+result+"' anymore - we detected it correctly.");
                }
            } else {
                System.err.println("Note: Didn't detect version so we'll use your requested --"+whichVer+"ver "+prevVer);
            	result = prevVer;
            	if(!rightMilestone.isEmpty()&&whichVer.equals("new")) {
            		System.err.println(" .. ignoring milestone indicator " + rightMilestone);
            		rightMilestone = "";
            	}
                if(!leftMilestone.isEmpty()&&!whichVer.equals("new")) {
                    leftMilestone="";
                }
            }
        }

        if(result == null) {
        	System.err.println("prevVer="+prevVer);
            System.err.println("Error: You'll need to use the option  \"--"+whichVer+"ver\"  because we could not detect an ICU version in " + UVERSION );
            throw new InternalError("Error: You'll need to use the option  \"--"+whichVer+"ver\"  because we could not detect an ICU version in " + UVERSION );
        }



        return result;
    }

    private static void printUsage(){
        System.out.println("Usage: StableAPI option* target*");
        System.out.println();
        System.out.println("Options:");
        System.out.println("    --help          Print this text");
        System.out.println("    --oldver        Version of old version of ICU (optional)");
        System.out.println("    --olddir        Directory that contains xml docs of old version");
        System.out.println("    --newver        Version of new version of ICU (optional)");
        System.out.println("    --newdir        Directory that contains xml docs of new version");
        System.out.println("    --cxslt         XSLT file for C docs");
        System.out.println("    --cppxslt       XSLT file for C++ docs");
        System.out.println("    --reportxslt    XSLT file for report docs");
        System.out.println("    --resultfile    Output file");
        System.exit(-1);
    }

    static String getAttr(Node node, String attrName){
    	if(node.getAttributes()==null && node.getNodeType()==3) {
//    		return "(text node 3)";
    		return "(Node: " + node.toString() + " )";
//    		return node.getFirstChild().getAttributes().getNamedItem(attrName).getNodeValue();
    	}

        try {
        	return node.getAttributes().getNamedItem(attrName).getNodeValue();
        } catch(NullPointerException npe) {
        	if(node.getAttributes()==null)  {
        		throw new InternalError("[no attributes Can't get attr "+attrName +" out of node " + node.getNodeName()+":"+node.getNodeType()+":"+node.getNodeValue()+"@"+node.getTextContent());
        	} else if(node.getAttributes().getNamedItem(attrName)==null) {
        		return null;
        		//throw new InternalError("No attribute named: "+attrName);
        	} else {
        		System.err.println("Can't get attr "+attrName+": "+npe.toString());
        	}
        	npe.printStackTrace();
        	throw new InternalError("Can't get attr "+attrName);
        }
    }

    static String getAttr(NamedNodeMap attrList, String attrName){
        return attrList.getNamedItem(attrName).getNodeValue();
    }

    static class Function implements Comparable<Function> {
        public String prototype;
        public String id;
        public String status;
        public String version;
        public String file;
        public String comparableName;
        public String comparablePrototype;
        public boolean equals(Function right){
            return this.comparablePrototype.equals(right.comparablePrototype);
        }
        static Function fromXml(Node n){
            Function f = new Function();
            f.prototype = getAttr(n, "prototype");

            if("yes".equals(getAttr(n, "static"))&&!f.prototype.contains("static")) {
            	f.prototype = "static ".concat(f.prototype);
            }

            f.id = getAttr(n, "id");
            f.status = getAttr(n, "status");
            f.version = trimICU(getAttr(n, "version"));
            f.file = getAttr(n, "file");
            f.purifyPrototype();

            f.simplifyPrototype();

            f.comparablePrototype = f.prototype;
            // Modify the prototype here, but don't display it to the user. ( Char16Ptr --> char16_t* etc )
            for(int i=0; i<aliasList.length; i+=2) {
                f.comparablePrototype = f.comparablePrototype.replaceAll(aliasList[i+0], aliasList[i+1]);
            }


            if(f.file == null) {
            	f.file = "{null}";
            } else {
            	f.file = Function.getBasename(f.file);
            }
            f.comparableName = f.comparableName();
            return f;
        }

        /**
         * Convert string to basename.
         * @param str
         * @return
         */
        private static String getBasename(String str){
            int i = str.lastIndexOf("/");
            str = i == -1 ? str : str.substring(i+1);
            return str;
        }


        static private String replList[] = {  "[ ]*\\([ ]*void[ ]*\\)", "() ",       // (void) => ()
                                              "[ ]*,", ", ",                         // No spaces preceding commas.
                                              "[ ]*\\*[ ]*", "* ",                   // No spaces preceding '*'.
                                              "[ ]*=[ ]*0[ ]*$", "=0 ",              // No spaces in " = 0".
                                              "[ ]{2,}", " ",   
                                              "\n", " "                     // Multiple spaces collapse to single.
            						};

        /**
         * these are noted as deltas.
         */
        static private String simplifyList[] = {
            "[ ]*=[ ]*0[ ]*$", "",      // remove pure virtual - TODO: notify about this difference, separately
            "[ ]*U_NOEXCEPT", "",       // remove U_NOEXCEPT (this was fixed in Doxyfile, but fixing here so it is retroactive)
            "[ ]*U_OVERRIDE", "",       // remove U_OVERRIDE
            "^([^\\* ]+)\\*(.*)::(clone|safeClone|cloneAsThawed|freeze|createBufferClone)\\((.*)", "void*$2::$3($4",
            "\\s+$", "",                 // remove trailing spaces.
            "^U_NAMESPACE_END ", "" // Bug in processing of uspoof.h
        };

        /**
         * This list is applied only for comparisons.
         * The resulting string is NOT shown to the user.
         * These should be ignored as far as changes go.   func(UChar) === func(char16_t)
         */
        static private String aliasList[] = {
            "UChar", "char16_t",
            "ConstChar16Ptr", "const char16_t*",
            "Char16Ptr", "char16_t*",
        };

        /**
         * Special cases:
         *
         * Remove the status attribute embedded in the C prototype
         *
         * Remove the virtual keyword in Cpp prototype
         */
        private void purifyPrototype(){
            //refer to 'umachine.h'
            String statusList[] = {"U_CAPI", "U_STABLE", "U_DRAFT", "U_DEPRECATED", "U_OBSOLETE", "U_INTERNAL", "virtual", "U_EXPORT2", "U_I18N_API", "U_COMMON_API" };
            for (int i = 0; i < statusList.length; i++) {
                String s = statusList[i];
                prototype = prototype.replaceAll(s,"");
                prototype = prototype.trim();
            }

            for (int i = 0; i < replList.length; i+= 2) {
                prototype = prototype.replaceAll(replList[i+0],replList[i+1]);
            }


            prototype = prototype.trim();

            // Now, remove parameter names!
            StringBuffer out = new StringBuffer();
            StringBuffer in = new StringBuffer(prototype);
            int openParen = in.indexOf("(");
            int closeParen = in.lastIndexOf(")");

            if(openParen==-1 || closeParen==-1) return; // exit, malformed?
            if(openParen+1==closeParen) return; // exit: ()

            out.append(in, 0, openParen+1); // prelude

            for(int left = openParen+1; left<closeParen;) {
            	int right = in.indexOf(",", left+1); // right edge
            	if(right>=closeParen || right==-1 )  right=closeParen; // found last comma

            //	System.err.println("Considering  " + left + " / " + right + " - " + closeParen +  " : "  + in.substring(left, right));

            	if(left==right) continue;

            	// find variable name
            	int rightCh = right-1;
            	if(rightCh==left) { // 1 ch- break
            		out.append(in,left,right);
            		continue;
            	}
            	// eat whitespace at right
            	int nameEndCh = rightCh;
            	while(nameEndCh>left && Character.isWhitespace(in.charAt(nameEndCh))) {
            		nameEndCh--;
            	}
            	int nameStartCh = nameEndCh;
            	while(nameStartCh>left && Character.isJavaIdentifierPart(in.charAt(nameStartCh))) {
            		nameStartCh--;
            	}

            	// now, did we find something to skip?
            	if(nameStartCh>left && nameEndCh>nameStartCh) {
            		out.append(in, left, nameStartCh+1);
            	} else {
            		// pass through
            		out.append(in, left, right);
            	}

            	left = right;
            }

            out.append(in, closeParen, in.length()); // postlude

            // Delete any doubled whitespace.
            for(int p=1;p<out.length();p++) {
                char prev = out.charAt(p-1);
            	if(Character.isWhitespace(prev)) {
            		while (out.length()>p&&(Character.isWhitespace(out.charAt(p)))) {
            			out.deleteCharAt(p);
            		}
            		if(out.length()>p) {
            			// any trailings to delete?
            			char curr = out.charAt(p);
            			if(curr==',' || curr==')' || curr=='*' || curr=='&') { // delete spaces before these.
            				out.deleteCharAt(--p);
            				continue;
            			}
            		}
            	}
            }

          //  System.err.println(prototype+" -> " + out.toString());
            prototype = out.toString();
        }

        private void simplifyPrototype() {
            if (prototype.startsWith("#define")) {
                return;
            }
            final String prototype0 = prototype;
            for (int i = 0; i < simplifyList.length; i+= 2) {
                prototype = prototype.replaceAll(simplifyList[i+0],simplifyList[i+1]);
            }
            if(!prototype0.equals(prototype)) {
                addSimplification(prototype0, prototype);
            }
        }
//        private Element toXml(Document doc){
//            Element  ele = doc.createElement("func");
//            ele.setAttribute("prototype", prototype);
//            ele.setAttribute("id", id);
//            ele.setAttribute("status", status);
//            return ele;
//        }

        /**
         * @Override
         */
		public int compareTo(Function o) {
			return comparableName.compareTo(((Function)o).comparableName);
		}
		public String comparableName() {
			return file+"|"+comparablePrototype+"|"+status+"|"+version+"|"+id;
		}
    }

    static class JoinedFunction implements Comparable<JoinedFunction> {
        public String prototype;
        public String leftRefId;
        public String leftStatus;
        public String leftVersion;
        public String rightVersion;
        public String leftFile;
        public String rightRefId;
        public String rightStatus;
        public String rightFile;

        public String comparableName;

        static JoinedFunction fromLeftFun(Function left){
            JoinedFunction u = new JoinedFunction();
            u.prototype = left.prototype;
            u.leftRefId = left.id;
            u.leftStatus = left.status;
            u.leftFile = left.file;
            u.rightRefId = notFound;
           // u.rightVersion = nul;
            u.leftVersion = left.version;
            u.rightStatus = notFound;
            u.rightFile = notFound;
            u.comparableName = left.comparableName;
            return u;
        }

        static JoinedFunction fromRightFun(Function right){
            JoinedFunction u = new JoinedFunction();
            u.prototype = right.prototype;
            u.leftRefId = notFound;
            u.leftStatus = notFound;
            u.leftFile = notFound;
           // u.leftVersion = nul;
            u.rightVersion = right.version;
            u.rightRefId = right.id;
            u.rightStatus = right.status;
            u.rightFile = right.file;
            u.comparableName = right.comparableName;
            return u;
        }

        static JoinedFunction fromTwoFun(Function left, Function right){
            if (!left.equals(right)) throw new Error();
            JoinedFunction u = new JoinedFunction();
            u.prototype = left.prototype;
            u.leftRefId = left.id;
            u.leftStatus = left.status;
            u.leftFile = left.file;
            u.rightRefId = right.id;
            u.rightStatus = right.status;
            u.leftVersion = left.version;
            u.rightVersion = right.version;
            u.rightFile = right.file;
            u.comparableName = left.comparableName+"+"+right.comparableName;
            return u;
        }

        Element toXml(Document doc){
            Element  ele = doc.createElement("func");
            ele.setAttribute("prototype", formatCode(prototype));
//            ele.setAttribute("leftRefId", leftRefId);

            ele.setAttribute("leftStatus", leftStatus);
//            ele.setAttribute("rightRefId", rightRefId);
            ele.setAttribute("rightStatus", rightStatus);
            ele.setAttribute("leftVersion", leftVersion);
//            ele.setAttribute("rightRefId", rightRefId);
            ele.setAttribute("rightVersion", rightVersion);


//            String f = rightRefId.equals(notFound) ? leftRefId : rightRefId;
//            int tail = f.indexOf("_");
//            f = tail != -1 ? f.substring(0, tail) : f;
//            f = f.startsWith("class") ? f.replaceFirst("class","") : f;
            String f = rightFile.equals(notFound) ? leftFile : rightFile;
            ele.setAttribute("file", f);
            return ele;
        }


		public int compareTo(JoinedFunction o) {
			return comparableName.compareTo(o.comparableName);
		}

        public boolean equals(Function right){
            return this.prototype.equals(right.prototype);
        }
    }

    TransformerFactory transFac = TransformerFactory.newInstance();
    Transformer makeTransformer(InputStream is, String name) {
    	if(is==null) {
    		throw new InternalError("No inputstream set for " + name);
    	}
    	System.err.println("Transforming from: " + name);
    	Transformer t;
		try {
//			// check the prolog
//			if(is.markSupported())  try {
//				is.mark(100);
//				int b = is.read();
//				is.reset();
//				System.err.println("Read byte: == " + Integer.toHexString(b));
//			} catch(Throwable th) {
//				System.err.println(" ( couldn't read a byte: " + th.toString()+ " )");
//			} else {
//				System.err.println(" ( couldn't set mark)");
//			}
			StreamSource ss = new StreamSource(is);
			ss.setSystemId(new File("."));
			t = transFac.newTransformer(ss);
		} catch (TransformerConfigurationException e) {
			e.printStackTrace();
			throw new InternalError("Couldn't make transformer for " + name + " - " + e.getMessageAndLocation());
		}
    	if(t == null) {
    		throw new InternalError("Couldn't make transformer for " + name);
    	}
    	return t;
    }
    private void reportSelectedFun(Node joinedNode) throws TransformerException, ParserConfigurationException, SAXException, IOException{
        Transformer report = makeTransformer(reportXslStream, RPTXSLT);
        //report.setParameter("leftStatus", leftStatus);
        report.setParameter("leftVer", leftVer);
//        report.setParameter("rightStatus", rightStatus);
        report.setParameter("ourYear", new Integer(new java.util.GregorianCalendar().get(java.util.Calendar.YEAR)));
        report.setParameter("rightVer", rightVer);
        report.setParameter("rightMilestone", rightMilestone);
        report.setParameter("leftMilestone", leftMilestone);
        report.setParameter("dateTime", new GregorianCalendar().getTime());
        report.setParameter("notFound", notFound);

        DOMSource src = new DOMSource(joinedNode);

        Result res = new StreamResult(resultFile);
//        DOMResult res = new DOMResult();
        report.transform(src, res);
//        dumpNode(res.getNode(),"");
    }

    private Set<JoinedFunction> getFullList(InputStream dumpXsltStream, String dumpXsltFile) throws TransformerException, ParserConfigurationException, XPathExpressionException, SAXException, IOException{
        // prepare transformer
        XPath xpath = XPathFactory.newInstance().newXPath();
        String expression = "/list";
        Transformer transformer = makeTransformer(dumpXsltStream, dumpXsltFile);

        //        InputSource leftSource = new InputSource(leftDir + "index.xml");
        DOMSource leftIndex = new DOMSource(getDocument(new File(leftDir,INDEX_XML)));
        DOMResult leftResult = new DOMResult();
        transformer.setParameter(DOC_FOLDER, leftDir);
        transformer.transform(leftIndex, leftResult);

//        Node leftList = XPathAPI.selectSingleNode(leftResult.getNode(),"/list");
        Node leftList = (Node)xpath.evaluate(expression, leftResult.getNode(), XPathConstants.NODE);
        if(leftList==null) {
           	//dumpNode(xsltSource.getNode());
          	dumpNode(leftResult.getNode());
//        	dumpNode(leftIndex.getNode());
        	System.out.flush();
        	System.err.flush();
        	throw new InternalError("getFullList("+dumpXsltFile.toString()+") returned a null left "+expression);
        }

        xpath.reset(); // reuse

        DOMSource rightIndex = new DOMSource(getDocument(new File(rightDir,INDEX_XML)));
        DOMResult rightResult = new DOMResult();
        transformer.setParameter(DOC_FOLDER, rightDir);
        System.err.println("Loading: "+dumpXsltFile.toString());
        transformer.transform(rightIndex, rightResult);
        System.err.println("   .. loaded: "+dumpXsltFile.toString());
        Node rightList = (Node)xpath.evaluate(expression, rightResult.getNode(), XPathConstants.NODE);
        if(rightList==null) {
        	throw new InternalError("getFullList("+dumpXsltFile.toString()+") returned a null right "+expression);
        }
//        dumpNode(rightList,"");


        Set<Function> leftSet = nodeToSet(leftList);
        Set<Function> rightSet = nodeToSet(rightList);
        Set<JoinedFunction> joined = fullJoin(leftSet, rightSet);
        return joined;
//        joinedNode = setToNode(joined);
//        dumpNode(joinedNode,"");
//        return joinedNode;
    }

    /**
     * @param node
     * @return      Set<Fun>
     */
    private Set<Function> nodeToSet(Node node){
        Set<Function> s = new TreeSet<Function>();
        NodeList list = node.getChildNodes();
        for (int i = 0; i < list.getLength(); i++) {
            Node n = list.item(i);
            s.add(Function.fromXml(n));
        }
        return s;
    }

    /**
     * @param set       Set<JoinedFun>
     * @return
     * @throws ParserConfigurationException
     */
    private Node setToNode(Set<JoinedFunction> set) throws ParserConfigurationException{
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        Document doc  = dbf.newDocumentBuilder().newDocument();
        Element root = doc.createElement("list");
        doc.appendChild(root);
        for (Iterator<JoinedFunction> iter = set.iterator(); iter.hasNext();) {
            JoinedFunction fun = iter.next();
            root.appendChild(fun.toXml(doc));
        }

        // add the 'changed' stuff
        Element root2 = doc.createElement("simplifications");
        root.appendChild(root2);
        {
        	for(String simplification : getChangedSimplifications()) {
        		Element subSimplification = doc.createElement("simplification");
        		Element baseElement = doc.createElement("base");
        		baseElement.appendChild(doc.createTextNode(simplification));
        		subSimplification.appendChild(baseElement);

        		root2.appendChild(subSimplification);

        		for(String change : simplifications.get(simplification)) {
        			Element changeElement = doc.createElement("change");
        			changeElement.appendChild(doc.createTextNode(change));
        			subSimplification.appendChild(changeElement);
        		}
	       	}
        }

        return doc;
    }

    /**
     * full-join two Set on 'prototype'
     *
     * @param left     Set<Fun>
     * @param right    Set<Fun>
     * @return          Set<JoinedFun>
     */
    private static Set<JoinedFunction> fullJoin(Set<Function> left, Set<Function> right){

        Set<JoinedFunction> joined = new TreeSet<JoinedFunction>(); //Set<JoinedFun>
        Set<Function> common = new TreeSet<Function>(); //Set<Fun>
        for (Iterator<Function> iter1 = left.iterator(); iter1.hasNext();) {
            Function f1 = iter1.next();
//            if (f1.prototype.matches(".*Transliterator::.*")){
//                System.err.println("left: " + f1.prototype);
//                System.err.println("left: " + f1.status);
//            }
            for (Iterator<Function> iter2 = right.iterator(); iter2.hasNext();) {
                Function f2 = iter2.next();
//                if ( f1.prototype.matches(".*filteredTransliterate.*")
//                  && f2.prototype.matches(".*filteredTransliterate.*")){
//                    System.err.println("right: " + f2.prototype);
//                    System.err.println("right: " + f2.status);
//                    System.err.println(f1.prototype.equals(f2.prototype));
//                    System.err.println(f1.prototype.getBytes()[0]);
//                    System.err.println(f2.prototype.getBytes()[0]);
//                }
                if (f1.equals(f2)) {
                    // should add left item to common set
                    // since we will remove common items with left set later
                    common.add(f1);
                    joined.add(JoinedFunction.fromTwoFun(f1, f2));
                    right.remove(f2);
                    break;
                }
            }
        }

        for (Iterator<Function> iter = common.iterator(); iter.hasNext();) {
            Function f = iter.next();
            left.remove(f);
        }

        for (Iterator<Function> iter = left.iterator(); iter.hasNext();) {
            Function f = iter.next();
            joined.add(JoinedFunction.fromLeftFun(f));
        }

        for (Iterator<Function> iter = right.iterator(); iter.hasNext();) {
            Function f = iter.next();
            joined.add(JoinedFunction.fromRightFun(f));
        }
        return joined;
    }

    private static void dumpNode(Node n) {
    	dumpNode(n,"");
    }
    /**
     * Dump out a node for debugging. Recursive fcn
     * @param n
     * @param pre
     */
    private static void dumpNode(Node n, String pre) {
    	String opre = pre;
		pre += " ";
		System.out.print(opre + "<" + n.getNodeName() );
		// dump attribute
		NamedNodeMap attr = n.getAttributes();
		if (attr != null) {
			for (int i = 0; i < attr.getLength(); i++) {
				System.out.print("\n"+pre+"   "+attr.item(i).getNodeName()+"=\"" + attr.item(i).getNodeValue()+"\"");
			}
		}
		System.out.println(">");

		// dump value
		String v = pre + n.getNodeValue();
		if (n.getNodeType() == Node.TEXT_NODE)
			System.out.println(v);

		// dump sub nodes
		NodeList nList = n.getChildNodes();
		for (int i = 0; i < nList.getLength(); i++) {
			Node ln = nList.item(i);
			dumpNode(ln, pre + " ");
		}
		System.out.println(opre + "</" + n.getNodeName() + ">");
	}

    private static DocumentBuilder theBuilder = null;
    private static DocumentBuilderFactory dbf  = null;
    private synchronized static DocumentBuilder getDocumentBuilder() throws ParserConfigurationException {
    	if(theBuilder == null) {
            dbf = DocumentBuilderFactory.newInstance();
            theBuilder = dbf.newDocumentBuilder();
    	}
    	return theBuilder;
    }

    private static Document getDocument(File file) throws ParserConfigurationException, SAXException, IOException{
        FileInputStream fis = new FileInputStream(file);
        InputSource inputSource = new InputSource(fis);
        Document doc = getDocumentBuilder().parse(inputSource);
        return doc;
    }
    static boolean tried = false;
    static Formatter aFormatter = null;

    public interface Formatter {
    	public String formatCode(String s);
    }


    public static String format_keywords[] = {
    	"enum","#define","static"
    };

    /**
     * Attempt to use a pretty formatter
     * @param prototype2
     * @return
     */
	public static String formatCode(String prototype2) {
		if(!tried) {
			String theFormatter = StableAPI.class.getPackage().getName()+".CodeFormatter";
			try {
				@SuppressWarnings("unchecked")
				Class<Formatter> formatClass = (Class<Formatter>) Class.forName(theFormatter);
				aFormatter = (Formatter) formatClass.newInstance();
			} catch (Exception e) {
				System.err.println("Note: Couldn't load " + theFormatter);
				aFormatter = new Formatter() {

					public String formatCode(String s) {
						String str = HTMLSafe(s.trim());
						for(String keyword : format_keywords) {
							if(str.startsWith(keyword)) {
								str = str.replaceFirst(keyword, "<tt>"+keyword+"</tt>");
							}
						}
						return str;
					}

				};
			}
			tried = true;
		}
		if(aFormatter != null) {
			return aFormatter.formatCode(prototype2);
		} else {
			return HTMLSafe(prototype2);
		}
	}

    public static String HTMLSafe(String s) {
        if(s==null) return null;

        return
            s.replaceAll("&","&amp;")
             .replaceAll("<","&lt;")
             .replaceAll(">","&gt;")
             .replaceAll("\"","&quot;");
    }


}
