package jdiff;

import com.sun.javadoc.*;
import com.sun.javadoc.Parameter;
import com.sun.javadoc.ParameterizedType;
import com.sun.javadoc.Type;

import java.util.*;
import java.io.*;
import java.lang.reflect.*;

/**
 * Converts a Javadoc RootDoc object into a representation in an 
 * XML file.
 *
 * See the file LICENSE.txt for copyright details.
 * @author Matthew Doar, mdoar@pobox.com
 */
public class RootDocToXML {

    /** Default constructor. */
    public RootDocToXML() {
    }

    /**
     * Write the XML representation of the API to a file.
     *
     * @param root  the RootDoc object passed by Javadoc
     * @return true if no problems encountered
     */
    public static boolean writeXML(RootDoc root) {
    	String tempFileName = outputFileName;
    	if (outputDirectory != null) {
	    tempFileName = outputDirectory;
	    if (!tempFileName.endsWith(JDiff.DIR_SEP)) 
		tempFileName += JDiff.DIR_SEP;
	    tempFileName += outputFileName;
    	}

        try {
            FileOutputStream fos = new FileOutputStream(tempFileName);
            outputFile = new PrintWriter(fos);
            System.out.println("JDiff: writing the API to file '" + tempFileName + "'...");
            if (root.specifiedPackages().length != 0 || root.specifiedClasses().length != 0) {
                RootDocToXML apiWriter = new RootDocToXML();
                apiWriter.emitXMLHeader();
                apiWriter.logOptions();
                apiWriter.processPackages(root);
                apiWriter.emitXMLFooter();
            }
            outputFile.close();
        } catch(IOException e) {
            System.out.println("IO Error while attempting to create " + tempFileName);
            System.out.println("Error: " +  e.getMessage());
            System.exit(1);
        }
        // If validation is desired, write out the appropriate api.xsd file
        // in the same directory as the XML file.
        if (XMLToAPI.validateXML) {
            writeXSD();
        }
        return true;
    }

    /**
     * Write the XML Schema file used for validation.
     */
    public static void writeXSD() {
        String xsdFileName = outputFileName;
        if (outputDirectory == null) {
	    int idx = xsdFileName.lastIndexOf('\\');
	    int idx2 = xsdFileName.lastIndexOf('/');
	    if (idx == -1 && idx2 == -1) {
		xsdFileName = "";
	    } else if (idx == -1 && idx2 != -1) {
		xsdFileName = xsdFileName.substring(0, idx2);
	    } else if (idx != -1  && idx2 == -1) {
		xsdFileName = xsdFileName.substring(0, idx);
	    } else if (idx != -1  && idx2 != -1) {
		int max = idx2 > idx ? idx2 : idx;
		xsdFileName = xsdFileName.substring(0, max);
	    }
	} else {
	    xsdFileName = outputDirectory;
	    if (!xsdFileName.endsWith(JDiff.DIR_SEP)) 
		 xsdFileName += JDiff.DIR_SEP;
	}
        xsdFileName += "api.xsd";
        try {
            FileOutputStream fos = new FileOutputStream(xsdFileName);
            PrintWriter xsdFile = new PrintWriter(fos);
            // The contents of the api.xsd file
            xsdFile.println("<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"no\"?>");
            xsdFile.println("<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">");
            xsdFile.println("");
            xsdFile.println("<xsd:annotation>");
            xsdFile.println("  <xsd:documentation>");
            xsdFile.println("  Schema for JDiff API representation.");
            xsdFile.println("  </xsd:documentation>");
            xsdFile.println("</xsd:annotation>");
            xsdFile.println();
            xsdFile.println("<xsd:element name=\"api\" type=\"apiType\"/>");
            xsdFile.println("");
            xsdFile.println("<xsd:complexType name=\"apiType\">");
            xsdFile.println("  <xsd:sequence>");
            xsdFile.println("    <xsd:element name=\"package\" type=\"packageType\" minOccurs='1' maxOccurs='unbounded'/>");
            xsdFile.println("  </xsd:sequence>");
            xsdFile.println("  <xsd:attribute name=\"name\" type=\"xsd:string\"/>");
            xsdFile.println("  <xsd:attribute name=\"jdversion\" type=\"xsd:string\"/>");
            xsdFile.println("</xsd:complexType>");
            xsdFile.println();
            xsdFile.println("<xsd:complexType name=\"packageType\">");
            xsdFile.println("  <xsd:sequence>");
            xsdFile.println("    <xsd:choice maxOccurs='unbounded'>");
            xsdFile.println("      <xsd:element name=\"class\" type=\"classType\"/>");
            xsdFile.println("      <xsd:element name=\"interface\" type=\"classType\"/>");
            xsdFile.println("    </xsd:choice>");
            xsdFile.println("    <xsd:element name=\"doc\" type=\"xsd:string\" minOccurs='0' maxOccurs='1'/>");
            xsdFile.println("  </xsd:sequence>");
            xsdFile.println("  <xsd:attribute name=\"name\" type=\"xsd:string\"/>");
            xsdFile.println("</xsd:complexType>");
            xsdFile.println();
            xsdFile.println("<xsd:complexType name=\"classType\">");
            xsdFile.println("  <xsd:sequence>");
            xsdFile.println("    <xsd:element name=\"implements\" type=\"interfaceTypeName\" minOccurs='0' maxOccurs='unbounded'/>");
            xsdFile.println("    <xsd:element name=\"constructor\" type=\"constructorType\" minOccurs='0' maxOccurs='unbounded'/>");
            xsdFile.println("    <xsd:element name=\"method\" type=\"methodType\" minOccurs='0' maxOccurs='unbounded'/>");
            xsdFile.println("    <xsd:element name=\"field\" type=\"fieldType\" minOccurs='0' maxOccurs='unbounded'/>");
            xsdFile.println("    <xsd:element name=\"doc\" type=\"xsd:string\" minOccurs='0' maxOccurs='1'/>");
            xsdFile.println("  </xsd:sequence>");
            xsdFile.println("  <xsd:attribute name=\"name\" type=\"xsd:string\"/>");
            xsdFile.println("  <xsd:attribute name=\"extends\" type=\"xsd:string\" use='optional'/>");
            xsdFile.println("  <xsd:attribute name=\"abstract\" type=\"xsd:boolean\"/>");
            xsdFile.println("  <xsd:attribute name=\"src\" type=\"xsd:string\" use='optional'/>");
            xsdFile.println("  <xsd:attribute name=\"static\" type=\"xsd:boolean\"/>");
            xsdFile.println("  <xsd:attribute name=\"final\" type=\"xsd:boolean\"/>");
            xsdFile.println("  <xsd:attribute name=\"deprecated\" type=\"xsd:string\"/>");
            xsdFile.println("  <xsd:attribute name=\"visibility\" type=\"xsd:string\"/>");
            xsdFile.println("</xsd:complexType>");
            xsdFile.println();
            xsdFile.println("<xsd:complexType name=\"interfaceTypeName\">");
            xsdFile.println("  <xsd:attribute name=\"name\" type=\"xsd:string\"/>");
            xsdFile.println("</xsd:complexType>");
            xsdFile.println();
            xsdFile.println("<xsd:complexType name=\"constructorType\">");
            xsdFile.println("  <xsd:sequence>");
            xsdFile.println("    <xsd:element name=\"exception\" type=\"exceptionType\" minOccurs='0' maxOccurs='unbounded'/>");
            xsdFile.println("    <xsd:element name=\"doc\" type=\"xsd:string\" minOccurs='0' maxOccurs='1'/>");
            xsdFile.println("  </xsd:sequence>");
            xsdFile.println("  <xsd:attribute name=\"name\" type=\"xsd:string\"/>");
            xsdFile.println("  <xsd:attribute name=\"type\" type=\"xsd:string\" use='optional'/>");
            xsdFile.println("  <xsd:attribute name=\"src\" type=\"xsd:string\" use='optional'/>");
            xsdFile.println("  <xsd:attribute name=\"static\" type=\"xsd:boolean\"/>");
            xsdFile.println("  <xsd:attribute name=\"final\" type=\"xsd:boolean\"/>");
            xsdFile.println("  <xsd:attribute name=\"deprecated\" type=\"xsd:string\"/>");
            xsdFile.println("  <xsd:attribute name=\"visibility\" type=\"xsd:string\"/>");
            xsdFile.println("</xsd:complexType>");
            xsdFile.println();
            xsdFile.println("<xsd:complexType name=\"paramsType\">");
            xsdFile.println("  <xsd:attribute name=\"name\" type=\"xsd:string\"/>");
            xsdFile.println("  <xsd:attribute name=\"type\" type=\"xsd:string\"/>");
            xsdFile.println("</xsd:complexType>");
            xsdFile.println();
            xsdFile.println("<xsd:complexType name=\"exceptionType\">");
            xsdFile.println("  <xsd:attribute name=\"name\" type=\"xsd:string\"/>");
            xsdFile.println("  <xsd:attribute name=\"type\" type=\"xsd:string\"/>");
            xsdFile.println("</xsd:complexType>");
            xsdFile.println();
            xsdFile.println("<xsd:complexType name=\"methodType\">");
            xsdFile.println("  <xsd:sequence>");
            xsdFile.println("    <xsd:element name=\"param\" type=\"paramsType\" minOccurs='0' maxOccurs='unbounded'/>");
            xsdFile.println("    <xsd:element name=\"exception\" type=\"exceptionType\" minOccurs='0' maxOccurs='unbounded'/>");
            xsdFile.println("    <xsd:element name=\"doc\" type=\"xsd:string\" minOccurs='0' maxOccurs='1'/>");
            xsdFile.println("  </xsd:sequence>");
            xsdFile.println("  <xsd:attribute name=\"name\" type=\"xsd:string\"/>");
            xsdFile.println("  <xsd:attribute name=\"return\" type=\"xsd:string\" use='optional'/>");
            xsdFile.println("  <xsd:attribute name=\"abstract\" type=\"xsd:boolean\"/>");
            xsdFile.println("  <xsd:attribute name=\"native\" type=\"xsd:boolean\"/>");
            xsdFile.println("  <xsd:attribute name=\"synchronized\" type=\"xsd:boolean\"/>");
            xsdFile.println("  <xsd:attribute name=\"src\" type=\"xsd:string\" use='optional'/>");
            xsdFile.println("  <xsd:attribute name=\"static\" type=\"xsd:boolean\"/>");
            xsdFile.println("  <xsd:attribute name=\"final\" type=\"xsd:boolean\"/>");
            xsdFile.println("  <xsd:attribute name=\"deprecated\" type=\"xsd:string\"/>");
            xsdFile.println("  <xsd:attribute name=\"visibility\" type=\"xsd:string\"/>");
            xsdFile.println("</xsd:complexType>");
            xsdFile.println();
            xsdFile.println("<xsd:complexType name=\"fieldType\">");
            xsdFile.println("  <xsd:sequence>");
            xsdFile.println("    <xsd:element name=\"doc\" type=\"xsd:string\" minOccurs='0' maxOccurs='1'/>");
            xsdFile.println("  </xsd:sequence>");
            xsdFile.println("  <xsd:attribute name=\"name\" type=\"xsd:string\"/>");
            xsdFile.println("  <xsd:attribute name=\"type\" type=\"xsd:string\"/>");
            xsdFile.println("  <xsd:attribute name=\"transient\" type=\"xsd:boolean\"/>");
            xsdFile.println("  <xsd:attribute name=\"volatile\" type=\"xsd:boolean\"/>");
            xsdFile.println("  <xsd:attribute name=\"value\" type=\"xsd:string\" use='optional'/>");
            xsdFile.println("  <xsd:attribute name=\"src\" type=\"xsd:string\" use='optional'/>");
            xsdFile.println("  <xsd:attribute name=\"static\" type=\"xsd:boolean\"/>");
            xsdFile.println("  <xsd:attribute name=\"final\" type=\"xsd:boolean\"/>");
            xsdFile.println("  <xsd:attribute name=\"deprecated\" type=\"xsd:string\"/>");
            xsdFile.println("  <xsd:attribute name=\"visibility\" type=\"xsd:string\"/>");
            xsdFile.println("</xsd:complexType>");
            xsdFile.println();
            xsdFile.println("</xsd:schema>");
            xsdFile.close();
        } catch(IOException e) {
            System.out.println("IO Error while attempting to create " + xsdFileName);
            System.out.println("Error: " +  e.getMessage());
            System.exit(1);
        }
    }

    /**
     * Write the options which were used to generate this XML file
     * out as XML comments.
     */
    public void logOptions() {
        outputFile.print("<!-- ");
        outputFile.print(" Command line arguments = " + Options.cmdOptions);
        outputFile.println(" -->");
    }

    /**
     * Process each package and the classes/interfaces within it.
     *
     * @param pd  an array of PackageDoc objects
     */
    public void processPackages(RootDoc root) {
        PackageDoc[] specified_pd = root.specifiedPackages();
	Map pdl = new TreeMap();
        for (int i = 0; specified_pd != null && i < specified_pd.length; i++) {
	    pdl.put(specified_pd[i].name(), specified_pd[i]);
	}

	// Classes may be specified separately, so merge their packages into the
	// list of specified packages.
        ClassDoc[] cd = root.specifiedClasses();
	// This is lists of the specific classes to document
	Map classesToUse = new HashMap();
        for (int i = 0; cd != null && i < cd.length; i++) {
	    PackageDoc cpd = cd[i].containingPackage();
	    if (cpd == null && !packagesOnly) {
		// If the RootDoc object has been created from a jar file
		// this duplicates classes, so we have to be able to disable it.
		// TODO this is still null?
		cpd = root.packageNamed("anonymous");
	    }
            String pkgName = cpd.name();
            String className = cd[i].name();
	    if (trace) System.out.println("Found package " + pkgName + " for class " + className);
	    if (!pdl.containsKey(pkgName)) {
		if (trace) System.out.println("Adding new package " + pkgName);
		pdl.put(pkgName, cpd);
	    }

	    // Keep track of the specific classes to be used for this package
	    List classes;
	    if (classesToUse.containsKey(pkgName)) {
		classes = (ArrayList) classesToUse.get(pkgName);
	    } else {
		classes = new ArrayList();
	    }
	    classes.add(cd[i]);
	    classesToUse.put(pkgName, classes);
	}

	PackageDoc[] pd = (PackageDoc[]) pdl.values().toArray(new PackageDoc[0]);
        for (int i = 0; pd != null && i < pd.length; i++) {
            String pkgName = pd[i].name();
            
            // Check for an exclude tag in the package doc block, but not
	    // in the package.htm[l] file.
            if (!shownElement(pd[i], null))
                continue;

            if (trace) System.out.println("PROCESSING PACKAGE: " + pkgName);
            outputFile.println("<package name=\"" + pkgName + "\">");

            int tagCount = pd[i].tags().length;
            if (trace) System.out.println("#tags: " + tagCount);
            
            List classList;
	    if (classesToUse.containsKey(pkgName)) {
		// Use only the specified classes in the package
		System.out.println("Using the specified classes");
		classList = (ArrayList) classesToUse.get(pkgName);
	    } else {
		// Use all classes in the package
		classList = new LinkedList(Arrays.asList(pd[i].allClasses()));
	    }
            Collections.sort(classList);
            ClassDoc[] classes = new ClassDoc[classList.size()];
            classes = (ClassDoc[])classList.toArray(classes);
            processClasses(classes, pkgName);

            addPkgDocumentation(root, pd[i], 2);

            outputFile.println("</package>");
        }
    } // processPackages
    
    /**
     * Process classes and interfaces.
     *
     * @param cd An array of ClassDoc objects.
     */
    public void processClasses(ClassDoc[] cd, String pkgName) {
        if (cd.length == 0)
            return;
        if (trace) System.out.println("PROCESSING CLASSES, number=" + cd.length);
        for (int i = 0; i < cd.length; i++) {
            String className = cd[i].name();
            if (trace) System.out.println("PROCESSING CLASS/IFC: " + className);
            // Only save the shown elements
            if (!shownElement(cd[i], classVisibilityLevel))
                continue;
            boolean isInterface = false;
            if (cd[i].isInterface())
                isInterface = true;
            if (isInterface) {
                outputFile.println("  <!-- start interface " + pkgName + "." + className + " -->");
                outputFile.print("  <interface name=\"" + className + "\"");
            } else {
                outputFile.println("  <!-- start class " + pkgName + "." + className + " -->");
                outputFile.print("  <class name=\"" + className + "\"");
            }
            // Add attributes to the class element
            Type parent = cd[i].superclassType();
            if (parent != null)
                outputFile.println(" extends=\"" + buildEmittableTypeString(parent) + "\"");
            outputFile.println("    abstract=\"" + cd[i].isAbstract() + "\"");
            addCommonModifiers(cd[i], 4);
            outputFile.println(">");
            // Process class members. (Treat inner classes as members.)
            processInterfaces(cd[i].interfaceTypes());
            processConstructors(cd[i].constructors());
            processMethods(cd[i], cd[i].methods());
            processFields(cd[i].fields());

            addDocumentation(cd[i], 4);

            if (isInterface) {
                outputFile.println("  </interface>");
                outputFile.println("  <!-- end interface " + pkgName + "." + className + " -->");
            } else {
                outputFile.println("  </class>");
                outputFile.println("  <!-- end class " + pkgName + "." + className + " -->");
            }
            // Inner classes have already been added.
            /*
              ClassDoc[] ic = cd[i].innerClasses();
              for (int k = 0; k < ic.length; k++) {
              System.out.println("Inner class " + k + ", name = " + ic[k].name());
              } 
            */
        }//for
    }//processClasses()
    
    /**
     * Add qualifiers for the program element as attributes.
     *
     * @param ped The given program element.
     */
    public void addCommonModifiers(ProgramElementDoc ped, int indent) {
        addSourcePosition(ped, indent);
        // Static and final and visibility on one line
        for (int i = 0; i < indent; i++) outputFile.print(" ");
        outputFile.print("static=\"" + ped.isStatic() + "\"");
        outputFile.print(" final=\"" + ped.isFinal() + "\"");
        // Visibility
        String visibility = null;
        if (ped.isPublic())
            visibility = "public";
        else if (ped.isProtected())
            visibility = "protected";
        else if (ped.isPackagePrivate())
            visibility = "package";
        else if (ped.isPrivate())
            visibility = "private";
        outputFile.println(" visibility=\"" + visibility + "\"");

        // Deprecation on its own line
        for (int i = 0; i < indent; i++) outputFile.print(" ");
        boolean isDeprecated = false;
        Tag[] ta = ((Doc)ped).tags("deprecated");
        if (ta.length != 0) {
            isDeprecated = true;
        }
        if (ta.length > 1) {
            System.out.println("JDiff: warning: multiple @deprecated tags found in comments for " + ped.name() + ". Using the first one only.");
            System.out.println("Text is: " + ((Doc)ped).getRawCommentText());
        }
        if (isDeprecated) {
            String text = ta[0].text(); // Use only one @deprecated tag
            if (text != null && text.compareTo("") != 0) {
                int idx = endOfFirstSentence(text);
                if (idx == 0) {
                    // No useful comment
                    outputFile.print("deprecated=\"deprecated, no comment\"");
                } else {
                    String fs = null;
                    if (idx == -1)
                        fs = text;
                    else
                        fs = text.substring(0, idx+1);
                    String st = API.hideHTMLTags(fs);
                    outputFile.print("deprecated=\"" + st + "\"");
                }
            } else {
                outputFile.print("deprecated=\"deprecated, no comment\"");
            }
        } else {
            outputFile.print("deprecated=\"not deprecated\"");
        }

    } //addQualifiers()

    /**
     * Insert the source code details, if available.
     *
     * @param ped The given program element.
     */
    public void addSourcePosition(ProgramElementDoc ped, int indent) {
        if (!addSrcInfo)
            return;
        if (JDiff.javaVersion.startsWith("1.1") || 
            JDiff.javaVersion.startsWith("1.2") || 
            JDiff.javaVersion.startsWith("1.3")) {
            return; // position() only appeared in J2SE1.4
        }
        try {
            // Could cache the method for improved performance
            Class c = ProgramElementDoc.class;
            Method m = c.getMethod("position", (Class[]) null);
            Object sp = m.invoke(ped, (Object[]) null);
            if (sp != null) {
                for (int i = 0; i < indent; i++) outputFile.print(" ");
                outputFile.println("src=\"" + sp + "\"");
            }
        } catch (NoSuchMethodException e2) {
            System.err.println("Error: method \"position\" not found");
            e2.printStackTrace();
        } catch (IllegalAccessException e4) {
            System.err.println("Error: class not permitted to be instantiated");
            e4.printStackTrace();
        } catch (InvocationTargetException e5) {
            System.err.println("Error: method \"position\" could not be invoked");
            e5.printStackTrace();
        } catch (Exception e6) {
            System.err.println("Error: ");
            e6.printStackTrace();
        }
    }

    /**
     * Process the interfaces implemented by the class.
     *
     * @param ifaces An array of ClassDoc objects
     */
    public void processInterfaces(Type[] ifaces) {
        if (trace) System.out.println("PROCESSING INTERFACES, number=" + ifaces.length);
        for (int i = 0; i < ifaces.length; i++) {
            String ifaceName = buildEmittableTypeString(ifaces[i]);
            if (trace) System.out.println("PROCESSING INTERFACE: " + ifaceName);
            outputFile.println("    <implements name=\"" + ifaceName + "\"/>");
        }//for
    }//processInterfaces()
    
    /**
     * Process the constructors in the class.
     *
     * @param ct An array of ConstructorDoc objects
     */
    public void processConstructors(ConstructorDoc[] ct) {
        if (trace) System.out.println("PROCESSING CONSTRUCTORS, number=" + ct.length);
        for (int i = 0; i < ct.length; i++) {
            String ctorName = ct[i].name();
            if (trace) System.out.println("PROCESSING CONSTRUCTOR: " + ctorName);
            // Only save the shown elements
            if (!shownElement(ct[i], memberVisibilityLevel))
                continue;
            outputFile.print("    <constructor name=\"" + ctorName + "\"");

            Parameter[] params = ct[i].parameters();
            boolean first = true;
            if (params.length != 0) {
                outputFile.print(" type=\"");
                for (int j = 0; j < params.length; j++) {
                    if (!first)
                        outputFile.print(", ");
                    emitType(params[j].type());
                    first = false;
                }
                outputFile.println("\"");
            } else
                outputFile.println();
            addCommonModifiers(ct[i], 6);
            outputFile.println(">");
            
            // Generate the exception elements if any exceptions are thrown
            processExceptions(ct[i].thrownExceptions());

            addDocumentation(ct[i], 6);

            outputFile.println("    </constructor>");
        }//for
    }//processConstructors()
    
    /**
     * Process all exceptions thrown by a constructor or method.
     *
     * @param cd An array of ClassDoc objects
     */
    public void processExceptions(ClassDoc[] cd) {
        if (trace) System.out.println("PROCESSING EXCEPTIONS, number=" + cd.length);
        for (int i = 0; i < cd.length; i++) {
            String exceptionName = cd[i].name();
            if (trace) System.out.println("PROCESSING EXCEPTION: " + exceptionName);
            outputFile.print("      <exception name=\"" + exceptionName + "\" type=\"");
            emitType(cd[i]);
            outputFile.println("\"/>");
        }//for
    }//processExceptions()
    
    /**
     * Process the methods in the class.
     *
     * @param md An array of MethodDoc objects
     */
    public void processMethods(ClassDoc cd, MethodDoc[] md) {
        if (trace) System.out.println("PROCESSING " +cd.name()+" METHODS, number = " + md.length);
        for (int i = 0; i < md.length; i++) {
            String methodName = md[i].name();
            if (trace) System.out.println("PROCESSING METHOD: " + methodName);
            // Skip <init> and <clinit>
            if (methodName.startsWith("<"))
                continue;
            // Only save the shown elements
            if (!shownElement(md[i], memberVisibilityLevel))
                continue;
            outputFile.print("    <method name=\"" + methodName + "\"");
            com.sun.javadoc.Type retType = md[i].returnType();
            if (retType.qualifiedTypeName().compareTo("void") == 0) {
                // Don't add a return attribute if the return type is void
                outputFile.println();
            } else {
                outputFile.print(" return=\"");
                emitType(retType);
                outputFile.println("\"");
            }
            outputFile.print("      abstract=\"" + md[i].isAbstract() + "\"");
            outputFile.print(" native=\"" + md[i].isNative() + "\"");
            outputFile.println(" synchronized=\"" + md[i].isSynchronized() + "\"");
            addCommonModifiers(md[i], 6);
            outputFile.println(">");
            // Generate the parameter elements, if any
            Parameter[] params = md[i].parameters();
            for (int j = 0; j < params.length; j++) {
                outputFile.print("      <param name=\"" + params[j].name() + "\"");
                outputFile.print(" type=\"");
                emitType(params[j].type());
                outputFile.println("\"/>");
            }

            // Generate the exception elements if any exceptions are thrown
            processExceptions(md[i].thrownExceptions());

            addDocumentation(md[i], 6);

            outputFile.println("    </method>");
        }//for
    }//processMethods()

    /**
     * Process the fields in the class.
     *
     * @param fd An array of FieldDoc objects
     */
    public void processFields(FieldDoc[] fd) {
        if (trace) System.out.println("PROCESSING FIELDS, number=" + fd.length);
        for (int i = 0; i < fd.length; i++) {
            String fieldName = fd[i].name();
            if (trace) System.out.println("PROCESSING FIELD: " + fieldName);
            // Only save the shown elements
            if (!shownElement(fd[i], memberVisibilityLevel))
                continue;
            outputFile.print("    <field name=\"" + fieldName + "\"");
            outputFile.print(" type=\"");
            emitType(fd[i].type());
            outputFile.println("\"");
            outputFile.print("      transient=\"" + fd[i].isTransient() + "\"");
            outputFile.println(" volatile=\"" + fd[i].isVolatile() + "\"");
/* JDK 1.4 and later */
/*
            String value = fd[i].constantValueExpression();
            if (value != null)
                outputFile.println(" value=\"" + value + "\"");
*/
            addCommonModifiers(fd[i], 6);
            outputFile.println(">");

            addDocumentation(fd[i], 6);

            outputFile.println("    </field>");

        }//for
    }//processFields()
    
    /**
     * Emit the type name. Removed any prefixed warnings about ambiguity.
     * The type maybe an array.
     *
     * @param type A Type object.
     */
    public void emitType(com.sun.javadoc.Type type) {
        String name = buildEmittableTypeString(type);
        if (name == null)
            return;
        outputFile.print(name);
    }

    /**
     * Build the emittable type name. The type may be an array and/or
     * a generic type.
     *
     * @param type A Type object
     * @return The emittable type name
     */
    private String buildEmittableTypeString(com.sun.javadoc.Type type) {
        if (type == null) {
    	    return null;
        }
      // type.toString() returns the fully qualified name of the type
      // including the dimension and the parameters we just need to
      // escape the generic parameters brackets so that the XML
      // generated is correct
      String name = type.toString().replaceAll("<", "&lt;").replaceAll(">", "&gt;");
      if (name.startsWith("<<ambiguous>>")) {
          name = name.substring(13);
      }
      return name;
    }    

    /**
     * Emit the XML header.
     */
    public void emitXMLHeader() {
        outputFile.println("<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"no\"?>");
        outputFile.println("<!-- Generated by the JDiff Javadoc doclet -->");
        outputFile.println("<!-- (" + JDiff.jDiffLocation + ") -->");
        outputFile.println("<!-- on " + new Date() + " -->");
        outputFile.println();
/* No need for this any longer, since doc block text is in an CDATA element
        outputFile.println("<!-- XML Schema is used, but XHTML transitional DTD is needed for nbsp -->");
        outputFile.println("<!-- entity definitions etc.-->");
        outputFile.println("<!DOCTYPE api");
        outputFile.println("     PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"");
        outputFile.println("     \"" + baseURI + "/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
*/
        outputFile.println("<api");
        outputFile.println("  xmlns:xsi='" + baseURI + "/2001/XMLSchema-instance'");
        outputFile.println("  xsi:noNamespaceSchemaLocation='api.xsd'");
        outputFile.println("  name=\"" + apiIdentifier + "\"");
        outputFile.println("  jdversion=\"" + JDiff.version + "\">");
        outputFile.println();
    }

    /**
     * Emit the XML footer.
     */
    public void emitXMLFooter() {
        outputFile.println();
        outputFile.println("</api>");
    }

    /** 
     * Determine if the program element is shown, according to the given 
     * level of visibility. 
     *
     * @param ped The given program element.
     * @param visLevel The desired visibility level; "public", "protected",
     *   "package" or "private". If null, only check for an exclude tag.
     * @return boolean Set if this element is shown.
     */
    public boolean shownElement(Doc doc, String visLevel) {
        // If a doc block contains @exclude or a similar such tag, 
        // then don't display it.
	if (doExclude && excludeTag != null && doc != null) {
            String rct = doc.getRawCommentText();
            if (rct != null && rct.indexOf(excludeTag) != -1) {
                return false;
	    }
	}  
	if (visLevel == null) {
	    return true;
	}
	ProgramElementDoc ped = null;
	if (doc instanceof ProgramElementDoc) {
	    ped = (ProgramElementDoc)doc;
	}
        if (visLevel.compareTo("private") == 0)
            return true;
        // Show all that is not private 
        if (visLevel.compareTo("package") == 0)
            return !ped.isPrivate();
        // Show all that is not private or package
        if (visLevel.compareTo("protected") == 0)
            return !(ped.isPrivate() || ped.isPackagePrivate());
        // Show all that is not private or package or protected,
        // i.e. all that is public
        if (visLevel.compareTo("public") == 0)
            return ped.isPublic();
        return false;
    } //shownElement()
    
    /** 
     * Strip out non-printing characters, replacing them with a character 
     * which will not change where the end of the first sentence is found.
     * This character is the hash mark, '&#035;'.
     */
    public String stripNonPrintingChars(String s, Doc doc) {
        if (!stripNonPrintables)
            return s;
        char[] sa = s.toCharArray();
        for (int i = 0; i < sa.length; i++) {
            char c = sa[i];
            // TODO still have an issue with Unicode: 0xfc in java.lang.String.toUpperCase comments
//            if (Character.isDefined(c))
            if (Character.isLetterOrDigit(c))
                continue;
            // There must be a better way that is still platform independent!
            if (c == ' ' ||
                c == '.' ||
                c == ',' ||
                c == '\r' ||
                c == '\t' ||
                c == '\n' ||
                c == '!' ||
                c == '?' ||
                c == ';' ||
                c == ':' ||
                c == '[' ||
                c == ']' ||
                c == '(' ||
                c == ')' ||
                c == '~' ||
                c == '@' ||
                c == '#' ||
                c == '$' ||
                c == '%' ||
                c == '^' ||
                c == '&' ||
                c == '*' ||
                c == '-' ||
                c == '=' ||
                c == '+' ||
                c == '_' ||
                c == '|' ||
                c == '\\' ||
                c == '/' ||
                c == '\'' ||
                c == '}' ||
                c == '{' ||
                c == '"' ||
                c == '<' ||
                c == '>' ||
                c == '`'
                )
                continue;
/* Doesn't seem to return the expected values?
            int val = Character.getNumericValue(c);
//            if (s.indexOf("which is also a test for non-printable") != -1)
//                System.out.println("** Char " + i + "[" + c + "], val =" + val); //DEBUG
            // Ranges from http://www.unicode.org/unicode/reports/tr20/
            // Should really replace 0x2028 and  0x2029 with <br/>
            if (val == 0x0 ||
                inRange(val, 0x2028, 0x2029) || 
                inRange(val, 0x202A, 0x202E) || 
                inRange(val, 0x206A, 0x206F) || 
                inRange(val, 0xFFF9, 0xFFFC) || 
                inRange(val, 0xE0000, 0xE007F)) {
                if (trace) {
                    System.out.println("Warning: changed non-printing character  " + sa[i] + " in " + doc.name()); 
                }
                sa[i] = '#';
            }
*/
            // Replace the non-printable character with a printable character
            // which does not change the end of the first sentence
            sa[i] = '#';
        }
        return new String(sa);
    }

    /** Return true if val is in the range [min|max], inclusive. */
    public boolean inRange(int val, int min, int max) {
        if (val < min)
            return false;
        if (val > max)
            return false;
        return true;
    }

    /** 
     * Add at least the first sentence from a doc block to the API. This is
     * used by the report generator if no comment is provided.
     * Need to make sure that HTML tags are not confused with XML tags.
     * This could be done by stuffing the &lt; character to another string
     * or by handling HTML in the parser. This second option seems neater. Note that
     * XML expects all element tags to have either a closing "/>" or a matching
     * end element tag. Due to the difficulties of converting incorrect HTML
     * to XHTML, the first option is used.
     */
    public void addDocumentation(ProgramElementDoc ped, int indent) {
        String rct = ((Doc)ped).getRawCommentText();
        if (rct != null) {
            rct = stripNonPrintingChars(rct, (Doc)ped);
            rct = rct.trim();
            if (rct.compareTo("") != 0 && 
                rct.indexOf(Comments.placeHolderText) == -1 &&
                rct.indexOf("InsertOtherCommentsHere") == -1) {
                int idx = endOfFirstSentence(rct);
                if (idx == 0)
                    return;
                for (int i = 0; i < indent; i++) outputFile.print(" ");
                outputFile.println("<doc>");
                for (int i = 0; i < indent; i++) outputFile.print(" ");
                String firstSentence = null;
                if (idx == -1)
                    firstSentence = rct;
                else
                    firstSentence = rct.substring(0, idx+1);
                boolean checkForAts = false;
                if (checkForAts && firstSentence.indexOf("@") != -1 && 
                    firstSentence.indexOf("@link") == -1) {
                    System.out.println("Warning: @ tag seen in comment: " + 
                                       firstSentence);
                }
                String firstSentenceNoTags = API.stuffHTMLTags(firstSentence);
                outputFile.println(firstSentenceNoTags);
                for (int i = 0; i < indent; i++) outputFile.print(" ");
                outputFile.println("</doc>");
            }
        }
    }

    /** 
     * Add at least the first sentence from a doc block for a package to the API. This is
     * used by the report generator if no comment is provided.
     * The default source tree may not include the package.html files, so
     * this may be unavailable in many cases.
     * Need to make sure that HTML tags are not confused with XML tags.
     * This could be done by stuffing the &lt; character to another string
     * or by handling HTML in the parser. This second option is neater. Note that
     * XML expects all element tags to have either a closing "/>" or a matching
     * end element tag.  Due to the difficulties of converting incorrect HTML
     * to XHTML, the first option is used.
     */
    public void addPkgDocumentation(RootDoc root, PackageDoc pd, int indent) {
        String rct = null;
        String filename = pd.name();
        try {
            // See if the source path was specified as part of the
            // options and prepend it if it was.
            String srcLocation = null;
            String[][] options = root.options();
            for (int opt = 0; opt < options.length; opt++) {
                if ((options[opt][0]).compareTo("-sourcepath") == 0) {
                    srcLocation = options[opt][1];
                    break;
                }
            }
            filename = filename.replace('.', JDiff.DIR_SEP.charAt(0));
            if (srcLocation != null) {
                // Make a relative location absolute 
                if (srcLocation.startsWith("..")) {
                    String curDir = System.getProperty("user.dir");
                    while (srcLocation.startsWith("..")) {
                        srcLocation = srcLocation.substring(3);
                        int idx = curDir.lastIndexOf(JDiff.DIR_SEP);
                        curDir = curDir.substring(0, idx+1);
                    }
                    srcLocation = curDir + srcLocation;
                }
                filename = srcLocation + JDiff.DIR_SEP + filename;
            }
            // Try both ".htm" and ".html"
            filename += JDiff.DIR_SEP + "package.htm";
            File f2 = new File(filename);
            if (!f2.exists()) {
                filename += "l";
            }
            FileInputStream f = new FileInputStream(filename);
            BufferedReader d = new BufferedReader(new InputStreamReader(f));
            String str = d.readLine();
 	    // Ignore everything except the lines between <body> elements
	    boolean inBody = false;
	    while(str != null) {
                if (!inBody) {
		    if (str.toLowerCase().trim().startsWith("<body")) {
			inBody = true;
		    }
		    str = d.readLine(); // Get the next line
		    continue; // Ignore the line
		} else {
		    if (str.toLowerCase().trim().startsWith("</body")) {
			inBody = false;
			continue; // Ignore the line
		    }
		}
                if (rct == null)
                    rct = str + "\n";
                else
                    rct += str + "\n";
                str = d.readLine();
            }
        }  catch(java.io.FileNotFoundException e) {
            // If it doesn't exist, that's fine
            if (trace)
                System.out.println("No package level documentation file at '" + filename + "'");
        } catch(java.io.IOException e) {
            System.out.println("Error reading file \"" + filename + "\": " + e.getMessage());
            System.exit(5);
        }     
        if (rct != null) {
            rct = stripNonPrintingChars(rct, (Doc)pd);
            rct = rct.trim();
            if (rct.compareTo("") != 0 &&
                rct.indexOf(Comments.placeHolderText) == -1 &&
                rct.indexOf("InsertOtherCommentsHere") == -1) {
                int idx = endOfFirstSentence(rct);
                if (idx == 0)
                    return;
                for (int i = 0; i < indent; i++) outputFile.print(" ");
                outputFile.println("<doc>");
                for (int i = 0; i < indent; i++) outputFile.print(" ");
                String firstSentence = null;
                if (idx == -1)
                    firstSentence = rct;
                else
                    firstSentence = rct.substring(0, idx+1);
                String firstSentenceNoTags = API.stuffHTMLTags(firstSentence);
                outputFile.println(firstSentenceNoTags);
                for (int i = 0; i < indent; i++) outputFile.print(" ");
                outputFile.println("</doc>");
            }
        }
    }

    /** 
     * Find the index of the end of the first sentence in the given text,
     * when writing out to an XML file.
     * This is an extended version of the algorithm used by the DocCheck 
     * Javadoc doclet. It checks for @tags too.
     *
     * @param text The text to be searched.
     * @return The index of the end of the first sentence. If there is no
     *         end, return -1. If there is no useful text, return 0.
     *         If the whole doc block comment is wanted (default), return -1.
     */
    public static int endOfFirstSentence(String text) {
        return endOfFirstSentence(text, true);
    }

    /** 
     * Find the index of the end of the first sentence in the given text.
     * This is an extended version of the algorithm used by the DocCheck 
     * Javadoc doclet. It checks for &#064;tags too.
     *
     * @param text The text to be searched.
     * @param writingToXML Set to true when writing out XML.
     * @return The index of the end of the first sentence. If there is no
     *         end, return -1. If there is no useful text, return 0.
     *         If the whole doc block comment is wanted (default), return -1.
     */
    public static int endOfFirstSentence(String text, boolean writingToXML) {
        if (saveAllDocs && writingToXML)
            return -1;
	int textLen = text.length();
	if (textLen == 0)
	    return 0;
        int index = -1;
        // Handle some special cases
        int fromindex = 0;
        int ellipsis = text.indexOf(". . ."); // Handles one instance of this
        if (ellipsis != -1)
            fromindex = ellipsis + 5;
        // If the first non-whitespace character is an @, go beyond it
        int i = 0;
        while (i < textLen && text.charAt(i) == ' ') {
            i++;
        }
        if (text.charAt(i) == '@' && fromindex < textLen-1)
            fromindex = i + 1;
        // Use the brute force approach.
        index = minIndex(index, text.indexOf("? ", fromindex));
        index = minIndex(index, text.indexOf("?\t", fromindex));
        index = minIndex(index, text.indexOf("?\n", fromindex));
        index = minIndex(index, text.indexOf("?\r", fromindex));
        index = minIndex(index, text.indexOf("?\f", fromindex));
        index = minIndex(index, text.indexOf("! ", fromindex));
        index = minIndex(index, text.indexOf("!\t", fromindex));
        index = minIndex(index, text.indexOf("!\n", fromindex));
        index = minIndex(index, text.indexOf("!\r", fromindex));
        index = minIndex(index, text.indexOf("!\f", fromindex));
        index = minIndex(index, text.indexOf(". ", fromindex));
        index = minIndex(index, text.indexOf(".\t", fromindex));
        index = minIndex(index, text.indexOf(".\n", fromindex));
        index = minIndex(index, text.indexOf(".\r", fromindex));
        index = minIndex(index, text.indexOf(".\f", fromindex));
        index = minIndex(index, text.indexOf("@param", fromindex));
        index = minIndex(index, text.indexOf("@return", fromindex));
        index = minIndex(index, text.indexOf("@throw", fromindex));
        index = minIndex(index, text.indexOf("@serial", fromindex));
        index = minIndex(index, text.indexOf("@exception", fromindex));
        index = minIndex(index, text.indexOf("@deprecate", fromindex));
        index = minIndex(index, text.indexOf("@author", fromindex));
        index = minIndex(index, text.indexOf("@since", fromindex));
        index = minIndex(index, text.indexOf("@see", fromindex));
        index = minIndex(index, text.indexOf("@version", fromindex));
        if (doExclude && excludeTag != null)
            index = minIndex(index, text.indexOf(excludeTag));
        index = minIndex(index, text.indexOf("@vtexclude", fromindex));
        index = minIndex(index, text.indexOf("@vtinclude", fromindex));
        index = minIndex(index, text.indexOf("<p>", 2)); // Not at start
        index = minIndex(index, text.indexOf("<P>", 2)); // Not at start
        index = minIndex(index, text.indexOf("<blockquote", 2));  // Not at start
        index = minIndex(index, text.indexOf("<pre", fromindex)); // May contain anything!
        // Avoid the char at the start of a tag in some cases
        if (index != -1 &&  
            (text.charAt(index) == '@' || text.charAt(index) == '<')) {
            if (index != 0)
                index--;
        }
        
/* Not used for jdiff, since tags are explicitly checked for above.
        // Look for a sentence terminated by an HTML tag.
        index = minIndex(index, text.indexOf(".<", fromindex));
        if (index == -1) {
            // If period-whitespace etc was not found, check to see if
            // last character is a period,
            int endIndex = text.length()-1;
            if (text.charAt(endIndex) == '.' ||
                text.charAt(endIndex) == '?' ||
                text.charAt(endIndex) == '!') 
                index = endIndex;
        }
*/
        return index;
    }
    
    /**
     * Return the minimum of two indexes if > -1, and return -1
     * only if both indexes = -1.
     * @param i an int index
     * @param j an int index
     * @return an int equal to the minimum index > -1, or -1
     */
    public static int minIndex(int i, int j) {
        if (i == -1) return j;
        if (j == -1) return i;
        return Math.min(i,j);
    }
    
    /** 
     * The name of the file where the XML representing the API will be 
     * stored. 
     */
    public static String outputFileName = null;

    /** 
     * The identifier of the API being written out in XML, e.g. 
     * &quotSuperProduct 1.3&quot;. 
     */
    public static String apiIdentifier = null;

    /** 
     * The file where the XML representing the API will be stored. 
     */
    private static PrintWriter outputFile = null;
    
    /** 
     * The name of the directory where the XML representing the API will be 
     * stored. 
     */
    public static String outputDirectory = null;

    /** 
     * Do not display a class  with a lower level of visibility than this. 
     * Default is to display all public and protected classes.
     */
    public static String classVisibilityLevel = "protected";

    /** 
     * Do not display a member with a lower level of visibility than this. 
     * Default is to display all public and protected members 
     * (constructors, methods, fields).
     */
    public static String memberVisibilityLevel = "protected";

    /** 
     * If set, then save the entire contents of a doc block comment in the 
     * API file. If not set, then just save the first sentence. Default is 
     * that this is set.
     */
    public static boolean saveAllDocs = true;

    /** 
     * If set, exclude program elements marked with whatever the exclude tag
     * is specified as, e.g. "@exclude".
     */
    public static boolean doExclude = false;

    /** 
     * Exclude program elements marked with this String, e.g. "@exclude".
     */
    public static String excludeTag = null;

    /** 
     * The base URI for locating necessary DTDs and Schemas. By default, this 
     * is "http://www.w3.org". A typical value to use local copies of DTD files
     * might be "file:///C:/jdiff/lib"
     */
    public static String baseURI = "http://www.w3.org";

    /** 
     * If set, then strip out non-printing characters from documentation.
     * Default is that this is set.
     */
    static boolean stripNonPrintables = true;

    /** 
     * If set, then add the information about the source file and line number
     * which is available in J2SE1.4. Default is that this is not set.
     */
    static boolean addSrcInfo = false;

    /** 
     * If set, scan classes with no packages. 
     * If the source is  a jar file this may duplicates classes, so 
     * disable it using the -packagesonly option. Default is that this is 
     * not set.
     */
    static boolean packagesOnly = false;

    /** Set to enable increased logging verbosity for debugging. */
    private static boolean trace = false;

} //RootDocToXML
