diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..16f62cc
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,11 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_SRC_FILES := $(filter-out %/JDiffAntTask.java,$(LOCAL_SRC_FILES))
+
+LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR)
+
+LOCAL_MODULE := jdiff
+
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/MODULE_LICENSE_LGPL b/MODULE_LICENSE_LGPL
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_LGPL
diff --git a/NOTICE.txt b/NOTICE.txt
new file mode 100644
index 0000000..fab48ed
--- /dev/null
+++ b/NOTICE.txt
@@ -0,0 +1,506 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
+
+
diff --git a/README.txt b/README.txt
new file mode 100755
index 0000000..9f7529e
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,59 @@
+
+                           JDiff Doclet
+                           ------------
+
+                           Matthew Doar
+                          mdoar@pobox.com
+
+
+The JDiff doclet is used to generate a report describing the
+difference between two public Java APIs. 
+
+The file jdiff.html contains the reference page for JDiff.  The latest
+version of JDiff can be downloaded at:
+http://sourceforge.net/projects/javadiff
+
+To use the Ant task on your own project, see example.xml. More examples
+of using JDiff to compare the public APIs of J2SE1.3 and J2SE1.4 can
+be seen at http://www.jdiff.org
+
+For an example with the source distribution, run "ant" and
+look at the HTML output in ./build/reports/example/changes.html 
+The page at ./build/reports/example/changes/com.acme.sp.SPImpl.html
+shows what a typical page of changes looks like. 
+
+System Requirements
+-------------------
+
+JDiff has been tested with all releases of Java since J2SE1.2 but
+releases of JDiff after 1.10.0 focus on JDK1.5.
+
+License
+-------
+
+JDiff is licensed under the Lesser GNU General Public License (LGPL).
+See the file LICENSE.txt.
+
+Acknowledgements
+----------------
+
+JDiff uses Stuart D. Gathman's Java translation of Gene Myers' O(ND) 
+difference algorithm.
+
+JDiff uses Xerces 1.4.2 from http://www.apache.org.
+
+JDiff also includes a script to use the classdoc application from
+http://classdoc.sourceforge.net or http://www.jensgulden.de, by Jens
+Gulden, (mail@jensgulden.de), to call a doclet such as jdiff on a .jar
+file rather than on source.
+
+Many thanks to the reviewers at Sun and Vitria who gave feedback on early
+versions of JDiff output, and also to the distillers of Laphroaig, and to
+Arturo Fuente for his consistently fine cigars which helped inspire
+much of this work.
+
+
+Footnote:
+
+If you are looking for a generalized diff tool for XML, try diffmk from
+http://wwws.sun.com/software/xml/developers/diffmk/
diff --git a/build.xml b/build.xml
new file mode 100755
index 0000000..3dd9657
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="jdiff" default="jar" basedir=".">
+
+<description>
+Builds Android's jdiff.jar and places it in device/extlibs/jdiff-1.1.0/. 
+</description>
+	 
+
+<target name="init" description="Properties used by other targets">
+  <property name="extlibs.dir" value="${basedir}/../../extlibs/jdiff-1.1.0/" />
+  <property name="src.dir" value="${basedir}/src" />
+  <property name="build.dir" value="build" />
+  <property name="classes.dir" value="${build.dir}/classes" />
+  <property name="lib.dir" value="${build.dir}/lib" />
+  <property name="version" value="1.1.0" />
+  <path id="class.path">
+    <pathelement location="{basedir}/../../extlibs/xerces.jar" />
+  </path>
+  <property name="debug" value="true" />
+  <property name="JDIFF_HOME" value="${extlibs.dir}" />
+</target>
+
+<target name="create.dirs" depends="init">
+  <mkdir dir="${build.dir}" />
+  <mkdir dir="${lib.dir}" />
+  <mkdir dir="${classes.dir}" />
+</target>
+
+<target	name="clean" depends="init">
+  <delete includeEmptyDirs="true"
+          verbose="false"
+          quiet="true">
+    <fileset dir="${build.dir}" />
+  </delete>
+</target>
+
+<target name="compile" depends="create.dirs" description="Compile everything except the Ant task">
+  <javac srcdir="${src.dir}"
+         destdir="${classes.dir}"
+         debug="${debug}"
+         excludes="jdiff/JDiffAntTask.java"
+         includeJavaRuntime="yes">
+    <classpath>
+      <path refid="class.path" />
+    </classpath>
+<!--<compilerarg value="-Xlint:unchecked"/>   -->
+  </javac>
+</target>	
+
+<!-- Place the jdiff.jar file in <branch-root>/device/extlibs/jdiff-.1.0/ (under version control) -->
+	<target name="jar" depends="compile">
+  <jar jarfile="${basedir}/jdiff.jar" 
+       basedir="${classes.dir}"
+       includes="*jdiff/*.class"
+       excludes="*jdiff/JDiffAntTask*.class" />
+</target>
+
+</project>
diff --git a/src/api.xsd b/src/api.xsd
new file mode 100755
index 0000000..bb2368f
--- /dev/null
+++ b/src/api.xsd
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+<xsd:annotation>
+  <xsd:documentation>
+  Schema for JDiff API representation.
+  </xsd:documentation>
+</xsd:annotation>
+
+<xsd:element name="api" type="apiType"/>
+
+<xsd:complexType name="apiType">
+  <xsd:sequence>
+    <xsd:element name="package" type="packageType" minOccurs='1' maxOccurs='unbounded'/>
+  </xsd:sequence>
+  <xsd:attribute name="name" type="xsd:string"/>
+  <xsd:attribute name="jdversion" type="xsd:string"/>
+</xsd:complexType>
+
+<xsd:complexType name="packageType">
+  <xsd:sequence>
+    <xsd:choice maxOccurs='unbounded'>
+      <xsd:element name="class" type="classType"/>
+      <xsd:element name="interface" type="classType"/>
+    </xsd:choice>
+    <xsd:element name="doc" type="xsd:string" minOccurs='0' maxOccurs='1'/>
+  </xsd:sequence>
+  <xsd:attribute name="name" type="xsd:string"/>
+</xsd:complexType>
+
+<xsd:complexType name="classType">
+  <xsd:sequence>
+    <xsd:element name="implements" type="interfaceTypeName" minOccurs='0' maxOccurs='unbounded'/>
+    <xsd:element name="constructor" type="constructorType" minOccurs='0' maxOccurs='unbounded'/>
+    <xsd:element name="method" type="methodType" minOccurs='0' maxOccurs='unbounded'/>
+    <xsd:element name="field" type="fieldType" minOccurs='0' maxOccurs='unbounded'/>
+    <xsd:element name="doc" type="xsd:string" minOccurs='0' maxOccurs='1'/>
+  </xsd:sequence>
+  <xsd:attribute name="name" type="xsd:string"/>
+  <xsd:attribute name="extends" type="xsd:string" use='optional'/>
+  <xsd:attribute name="abstract" type="xsd:boolean"/>
+  <xsd:attribute name="src" type="xsd:string" use='optional'/>
+  <xsd:attribute name="static" type="xsd:boolean"/>
+  <xsd:attribute name="final" type="xsd:boolean"/>
+  <xsd:attribute name="deprecated" type="xsd:string"/>
+  <xsd:attribute name="visibility" type="xsd:string"/>
+</xsd:complexType>
+
+<xsd:complexType name="interfaceTypeName">
+  <xsd:attribute name="name" type="xsd:string"/>
+</xsd:complexType>
+
+<xsd:complexType name="constructorType">
+  <xsd:sequence>
+    <xsd:element name="exception" type="exceptionType" minOccurs='0' maxOccurs='unbounded'/>
+    <xsd:element name="doc" type="xsd:string" minOccurs='0' maxOccurs='1'/>
+  </xsd:sequence>
+  <xsd:attribute name="name" type="xsd:string"/>
+  <xsd:attribute name="type" type="xsd:string" use='optional'/>
+  <xsd:attribute name="src" type="xsd:string" use='optional'/>
+  <xsd:attribute name="static" type="xsd:boolean"/>
+  <xsd:attribute name="final" type="xsd:boolean"/>
+  <xsd:attribute name="deprecated" type="xsd:string"/>
+  <xsd:attribute name="visibility" type="xsd:string"/>
+</xsd:complexType>
+
+<xsd:complexType name="paramsType">
+  <xsd:attribute name="name" type="xsd:string"/>
+  <xsd:attribute name="type" type="xsd:string"/>
+</xsd:complexType>
+
+<xsd:complexType name="exceptionType">
+  <xsd:attribute name="name" type="xsd:string"/>
+  <xsd:attribute name="type" type="xsd:string"/>
+</xsd:complexType>
+
+<xsd:complexType name="methodType">
+  <xsd:sequence>
+    <xsd:element name="param" type="paramsType" minOccurs='0' maxOccurs='unbounded'/>
+    <xsd:element name="exception" type="exceptionType" minOccurs='0' maxOccurs='unbounded'/>
+    <xsd:element name="doc" type="xsd:string" minOccurs='0' maxOccurs='1'/>
+  </xsd:sequence>
+  <xsd:attribute name="name" type="xsd:string"/>
+  <xsd:attribute name="return" type="xsd:string" use='optional'/>
+  <xsd:attribute name="abstract" type="xsd:boolean"/>
+  <xsd:attribute name="native" type="xsd:boolean"/>
+  <xsd:attribute name="synchronized" type="xsd:boolean"/>
+  <xsd:attribute name="src" type="xsd:string" use='optional'/>
+  <xsd:attribute name="static" type="xsd:boolean"/>
+  <xsd:attribute name="final" type="xsd:boolean"/>
+  <xsd:attribute name="deprecated" type="xsd:string"/>
+  <xsd:attribute name="visibility" type="xsd:string"/>
+</xsd:complexType>
+
+<xsd:complexType name="fieldType">
+  <xsd:sequence>
+    <xsd:element name="doc" type="xsd:string" minOccurs='0' maxOccurs='1'/>
+  </xsd:sequence>
+  <xsd:attribute name="name" type="xsd:string"/>
+  <xsd:attribute name="type" type="xsd:string"/>
+  <xsd:attribute name="transient" type="xsd:boolean"/>
+  <xsd:attribute name="volatile" type="xsd:boolean"/>
+  <xsd:attribute name="value" type="xsd:string" use='optional'/>
+  <xsd:attribute name="src" type="xsd:string" use='optional'/>
+  <xsd:attribute name="static" type="xsd:boolean"/>
+  <xsd:attribute name="final" type="xsd:boolean"/>
+  <xsd:attribute name="deprecated" type="xsd:string"/>
+  <xsd:attribute name="visibility" type="xsd:string"/>
+</xsd:complexType>
+
+</xsd:schema>
diff --git a/src/comments.xsd b/src/comments.xsd
new file mode 100755
index 0000000..cfee740
--- /dev/null
+++ b/src/comments.xsd
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+<xsd:annotation>
+  <xsd:documentation>
+  Schema for JDiff comments.
+  </xsd:documentation>
+</xsd:annotation>
+
+<xsd:element name="comments" type="commentsType"/>
+
+<xsd:complexType name="commentsType">
+  <xsd:sequence>
+    <xsd:element name="comment" type="commentType" minOccurs='0' maxOccurs='unbounded'/>
+  </xsd:sequence>
+  <xsd:attribute name="name" type="xsd:string"/>
+  <xsd:attribute name="jdversion" type="xsd:string"/>
+</xsd:complexType>
+
+<xsd:complexType name="commentType">
+  <xsd:sequence>
+    <xsd:element name="identifier" type="identifierType" minOccurs='1' maxOccurs='unbounded'/>
+    <xsd:element name="text" type="xsd:string" minOccurs='1' maxOccurs='1'/>
+  </xsd:sequence>
+</xsd:complexType>
+
+<xsd:complexType name="identifierType">
+  <xsd:attribute name="id" type="xsd:string"/>
+</xsd:complexType>
+
+</xsd:schema>
\ No newline at end of file
diff --git a/src/jdiff/API.java b/src/jdiff/API.java
new file mode 100755
index 0000000..2e8f117
--- /dev/null
+++ b/src/jdiff/API.java
@@ -0,0 +1,429 @@
+package jdiff;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * The internal representation of an API. 
+ * 
+ * RootDoc could have been used for representing this, but 
+ * you cannot serialize a RootDoc object - see
+ *  http://developer.java.sun.com/developer/bugParade/bugs/4125581.html
+ * You might be able use Javadoc.Main() to create another RootDoc, but the 
+ * methods are package private. You can run javadoc in J2SE1.4, see:
+ *  http://java.sun.com/j2se/1.4/docs/tooldocs/javadoc/standard-doclet.html#runningprogrammatically
+ * but you still can't get the RootDoc object.
+ *
+ * The advantage of writing out an XML representation of each API is that
+ * later runs of JDiff don't have to have Javadoc scan all the files again,
+ * a possibly lengthy process. XML also permits other source code in 
+ * languages other than Java to be scanned to produce XML, and then versions
+ * of JDiff can be used to create documents describing the difference in those
+ * APIs.
+ * 
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+public class API {
+
+    /** 
+     * The list of all the top-level packages. 
+     * Each package contains classes, each class contains members, and so on.
+     */
+    public List packages_; // PackageAPI[]
+
+    /** 
+     * The list of all the classes. 
+     * This is used to generate the methods and fields which are inherited,
+     * rather than storing them in the XML file.
+     */
+    public Hashtable classes_;
+
+    /** 
+     * The String which identifies this API, e.g. &quotSuperProduct 1.3&quot;.
+     */
+    public String name_ = null;
+
+    /** The current package being added to during parsing. */
+    public PackageAPI currPkg_ = null;
+    /** The current class being added to during parsing. */
+    public ClassAPI currClass_ = null;
+    /** The current constructor being added to during parsing. */
+    public ConstructorAPI currCtor_ = null;
+    /** The current method being added to during parsing. */
+    public MethodAPI currMethod_ = null;
+    /** The current field being added to during parsing. */
+    public FieldAPI currField_ = null;
+
+    /** Default constructor. */
+    public API() {
+        packages_ = new ArrayList(); //PackageAPI[]
+        classes_ = new Hashtable(); //ClassAPI
+    }   
+  
+//
+// Methods to display the contents of an API object.
+//
+
+    /** Amount by which to increment each indentation. */
+    public static final int indentInc = 2;
+
+    /** Display the contents of the API object. */
+    public void dump() {
+        int indent = 0;
+        Iterator iter = packages_.iterator();
+        while (iter.hasNext()) {
+            dumpPackage((PackageAPI)(iter.next()), indent);
+        }
+    }
+
+    /** 
+     * Display the contents of a PackageAPI object.
+     *
+     * @param pkg The given PackageAPI object.
+     * @param indent The number of spaces to indent the output.
+     */
+    public void dumpPackage(PackageAPI pkg, int indent) {
+        for (int i = 0; i < indent; i++) System.out.print(" ");
+        System.out.println("Package Name: " + pkg.name_);
+        Iterator iter = pkg.classes_.iterator();
+        while (iter.hasNext()) {
+            dumpClass((ClassAPI)(iter.next()), indent + indentInc);
+        }
+        // Display documentation
+        if (pkg.doc_ != null) {
+            System.out.print("Package doc block:");
+            System.out.println("\"" + pkg.doc_ + "\"");
+        }
+    }
+
+    /** 
+     * Display the contents of a ClassAPI object.
+     *
+     * @param c The given ClassAPI object.
+     * @param indent The number of spaces to indent the output.
+     */
+    public static void dumpClass(ClassAPI c, int indent) {
+        for (int i = 0; i < indent; i++) System.out.print(" ");
+        if (c.isInterface_)
+            System.out.println("Interface name: " + c.name_);
+        else
+            System.out.println("Class Name: " + c.name_);
+        if (c.extends_ != null) {
+            for (int i = 0; i < indent; i++) System.out.print(" ");
+            System.out.println("Extends: " + c.extends_);
+        }
+        if (c.implements_.size() != 0) {
+            for (int i = 0; i < indent; i++) System.out.print(" ");
+            System.out.println("Implements: ");
+            Iterator iter = c.implements_.iterator();
+            while (iter.hasNext()) {
+                String interfaceImpl = (String)(iter.next());
+                for (int i = 0; i < indent + 2; i++) System.out.print(" ");
+                System.out.println("  " + interfaceImpl);
+            }
+        }
+        // Dump modifiers specific to a class
+        if (c.isAbstract_)
+            System.out.print("abstract ");
+        // Dump modifiers common to all
+        dumpModifiers(c.modifiers_, indent);
+        // Dump ctors
+        Iterator iter = c.ctors_.iterator();
+        while (iter.hasNext()) {
+            dumpCtor((ConstructorAPI)(iter.next()), indent + indentInc);
+        }
+        // Dump methods
+        iter = c.methods_.iterator();
+        while (iter.hasNext()) {
+            dumpMethod((MethodAPI)(iter.next()), indent + indentInc);
+        }
+        // Dump fields
+        iter = c.fields_.iterator();
+        while (iter.hasNext()) {
+            dumpField((FieldAPI)(iter.next()), indent + indentInc);
+        }
+        // Display documentation
+        if (c.doc_ != null) {
+            System.out.print("Class doc block:");
+            System.out.println("\"" + c.doc_ + "\"");
+        } else
+            System.out.println();
+    }
+
+    /** 
+     * Display the contents of the Modifiers object.
+     *
+     * @param c The given Modifiers object.
+     * @param indent The number of spaces to indent the output.
+     */
+    public static void dumpModifiers(Modifiers m, int indent) {
+        for (int i = 0; i < indent; i++) System.out.print(" ");
+        if (m.isStatic)
+            System.out.print("static ");
+        if (m.isFinal)
+            System.out.print("final ");
+        if (m.visibility != null)
+            System.out.print("visibility = " + m.visibility + " ");
+        // Flush the line
+        System.out.println();
+    }
+
+    /** 
+     * Display the contents of a constructor.
+     *
+     * @param c The given constructor object.
+     * @param indent The number of spaces to indent the output.
+     */
+    public static void dumpCtor(ConstructorAPI c, int indent) {
+        for (int i = 0; i < indent; i++) System.out.print(" ");
+        System.out.println("Ctor type: " + c.type_);
+        // Display exceptions 
+        System.out.print("exceptions: " + c.exceptions_ + " ");
+        // Dump modifiers common to all
+        dumpModifiers(c.modifiers_, indent);
+        // Display documentation
+        if (c.doc_ != null) {
+            System.out.print("Ctor doc block:");
+            System.out.println("\"" + c.doc_ + "\"");
+        }
+    }
+
+    /** 
+     * Display the contents of a MethodAPI object.
+     *
+     * @param m The given MethodAPI object.
+     * @param indent The number of spaces to indent the output.
+     */
+    public static void dumpMethod(MethodAPI m, int indent) {
+        if (m.inheritedFrom_ != null)
+            return;
+        for (int i = 0; i < indent; i++) System.out.print(" ");
+        System.out.print("Method Name: " + m.name_);
+        if (m.inheritedFrom_ != null)
+            System.out.println(", inherited from: " + m.inheritedFrom_);
+        if (m.returnType_ != null)
+            System.out.println(", return type: " + m.returnType_);
+        else
+            System.out.println();
+        // Dump modifiers specific to a method
+        if (m.isAbstract_)
+            System.out.print("abstract ");
+        if (m.isNative_)
+            System.out.print("native ");
+        if (m.isSynchronized_)
+            System.out.print("synchronized ");
+        // Display exceptions 
+        System.out.print("exceptions: " + m.exceptions_ + " ");
+        // Dump modifiers common to all
+        dumpModifiers(m.modifiers_, indent);
+      
+        Iterator iter = m.params_.iterator();
+        while (iter.hasNext()) {
+            dumpParam((ParamAPI)(iter.next()), indent + indentInc);
+        }
+        // Display documentation
+        if (m.doc_ != null) {
+            System.out.print("Method doc block:");
+            System.out.println("\"" + m.doc_ + "\"");
+        }
+    }
+
+    /** 
+     * Display the contents of a field.
+     * Does not show inherited fields.
+     *
+     * @param f The given field object.
+     * @param indent The number of spaces to indent the output.
+     */
+    public static void dumpField(FieldAPI f, int indent) {
+        if (f.inheritedFrom_ != null)
+            return;
+        for (int i = 0; i < indent; i++) System.out.print(" ");
+        System.out.println("Field Name: " + f.name_ + ", type: " + f.type_);
+        if (f.inheritedFrom_ != null)
+            System.out.println(", inherited from: " + f.inheritedFrom_);
+        if (f.isTransient_)
+            System.out.print("transient ");
+        if (f.isVolatile_)
+            System.out.print("volatile ");
+        // Dump modifiers common to all
+        dumpModifiers(f.modifiers_, indent);
+        // Display documentation
+        if (f.doc_ != null)
+            System.out.print("Field doc block:");
+            System.out.println("\"" + f.doc_ + "\"");
+    }
+
+    /** 
+     * Display the contents of a parameter.
+     *
+     * @param p The given parameter object.
+     * @param indent The number of spaces to indent the output.
+     */
+    public static void dumpParam(ParamAPI p, int indent) {
+        for (int i = 0; i < indent; i++) System.out.print(" ");
+        System.out.println("Param Name: " + p.name_ + ", type: " + p.type_);
+    }
+
+    /** 
+     * Convert all HTML tags to text by placing them inside a CDATA element.
+     * Characters still have to be valid Unicode characters as defined by the 
+     * parser.
+     */
+    public static String stuffHTMLTags(String htmlText) {
+        if (htmlText.indexOf("]]>") != -1) {
+            System.out.println("Warning: illegal string ]]> found in text. Ignoring the comment.");
+            return "";
+        }
+        return "<![CDATA[" + htmlText + "]]>";
+    }
+
+    /**
+     * Convert all HTML tags to text by stuffing text into the HTML tag
+     * to stop it being an HTML or XML tag. E.g. &quot;<code>foo</code>&quot;
+     * becomes &quot;lEsS_tHaNcode>foolEsS_tHaN/code>&quot;. Replace all &lt; 
+     * characters
+     * with the string "lEsS_tHaN". Also replace &amp; character with the  
+     * string "aNd_cHaR" to avoid text entities. Also replace &quot; 
+     * character with the  
+     * string "qUoTe_cHaR".
+     */
+    public static String hideHTMLTags(String htmlText) {
+        StringBuffer sb = new StringBuffer(htmlText);
+        int i = 0;
+        while (i < sb.length()) {
+            if (sb.charAt(i) == '<') {
+                sb.setCharAt(i ,'l');
+                sb.insert(i+1, "EsS_tHaN");
+            } else if (sb.charAt(i) == '&') {
+                sb.setCharAt(i ,'a');
+                sb.insert(i+1, "Nd_cHaR");
+            } else if (sb.charAt(i) == '"') {
+                sb.setCharAt(i ,'q');
+                sb.insert(i+1, "uote_cHaR");
+            }
+            i++;
+        }
+        return sb.toString();
+    }
+
+    /** 
+     * Convert text with stuffed HTML tags ("lEsS_tHaN", etc) into HTML text.
+     */
+    public static String showHTMLTags(String text) {
+        StringBuffer sb = new StringBuffer(text);
+        StringBuffer res = new StringBuffer();
+        int len = sb.length();
+        res.setLength(len);
+        int i = 0;
+        int resIdx = 0;
+        while (i < len) {
+            char c = sb.charAt(i);
+            if (len - i > 8 && c == 'l' && 
+                sb.charAt(i+1) == 'E' &&
+                sb.charAt(i+2) == 's' &&
+                sb.charAt(i+3) == 'S' &&
+                sb.charAt(i+4) == '_' &&
+                sb.charAt(i+5) == 't' &&
+                sb.charAt(i+6) == 'H' &&
+                sb.charAt(i+7) == 'a' &&
+                sb.charAt(i+8) == 'N') {
+                res.setCharAt(resIdx ,'<');
+                i += 8;
+            } else if (len - i > 9 && c == 'q' && 
+                sb.charAt(i+1) == 'U' &&
+                sb.charAt(i+2) == 'o' &&
+                sb.charAt(i+3) == 'T' &&
+                sb.charAt(i+4) == 'e' &&
+                sb.charAt(i+5) == '_' &&
+                sb.charAt(i+6) == 'c' &&
+                sb.charAt(i+7) == 'H' &&
+                sb.charAt(i+8) == 'a' &&
+                sb.charAt(i+9) == 'R') {
+                res.setCharAt(resIdx ,'"');
+                i += 9;
+            } else if (len - i > 7 && c == 'a' && 
+                sb.charAt(i+1) == 'N' &&
+                sb.charAt(i+2) == 'd' &&
+                sb.charAt(i+3) == '_' &&
+                sb.charAt(i+4) == 'c' &&
+                sb.charAt(i+5) == 'H' &&
+                sb.charAt(i+6) == 'a' &&
+                sb.charAt(i+7) == 'R') {
+                res.setCharAt(resIdx ,'&');
+                i += 7;
+            } else {
+                res.setCharAt(resIdx, c);
+            }
+            i++;
+            resIdx++;
+        }
+        res.setLength(resIdx);
+        return res.toString();
+    }
+
+    /** 
+     * <b>NOT USED</b>. 
+     *
+     * Replace all instances of <p> with <p/>. Just for the small number
+     * of HMTL tags which don't require a matching end tag.
+     * Also make HTML conform to the simple HTML requirements such as 
+     * no double hyphens. Double hyphens are replaced by - and the character
+     * entity for a hyphen.
+     *
+     * Cases where this fails and has to be corrected in the XML by hand: 
+     *  Attributes' values missing their double quotes , e.g. size=-2
+     *  Mangled HTML tags e.g. &lt;ttt> 
+     *
+     * <p><b>NOT USED</b>. There is often too much bad HTML in
+     * doc blocks to try to handle every case correctly. Better just to
+     * stuff the *lt; and &amp: characters with stuffHTMLTags(). Though
+     * the resulting XML is not as elegant, it does the job with less
+     * intervention by the user.
+     */
+    public static String convertHTMLTagsToXHTML(String htmlText) {
+        StringBuffer sb = new StringBuffer(htmlText);
+        int i = 0;
+        boolean inTag = false;
+        String tag = null;
+        // Needs to re-evaluate this length at each loop
+        while (i < sb.length()) {
+            char c = sb.charAt(i);
+            if (inTag) {
+                if (c == '>') {
+                    // OPTION Could fail at or fix some errorneous tags here
+                    // Make the best guess as to whether this tag is terminated
+                    if (Comments.isMinimizedTag(tag) &&
+                        htmlText.indexOf("</" + tag + ">", i) == -1)
+                        sb.insert(i, "/");
+                    inTag = false;
+                } else {
+                    // OPTION could also make sure that attribute values are
+                    // surrounded by quotes.
+                    tag += c;
+                }
+            }
+            if (c == '<') {
+                inTag = true;
+                tag = "";
+            }
+            // -- is not allowed in XML, but !-- is part of an comment,
+            // and --> is also part of a comment
+            if (c == '-' && i > 0 && sb.charAt(i-1) == '-') {
+                if (!(i > 1 && sb.charAt(i-2) == '!')) { 
+                    sb.setCharAt(i, '&');
+                    sb.insert(i+1, "#045;");
+                    i += 5;
+                }
+            }
+            i++;
+        }
+        if (inTag) {
+            // Oops. Someone forgot to close their HTML tag, e.g. "<code."
+            // Close it for them.
+            sb.insert(i, ">");
+        }
+        return sb.toString();
+    }
+}
diff --git a/src/jdiff/APIComparator.java b/src/jdiff/APIComparator.java
new file mode 100755
index 0000000..b0f42ed
--- /dev/null
+++ b/src/jdiff/APIComparator.java
@@ -0,0 +1,934 @@
+package jdiff;
+
+import java.util.*;
+
+/**
+ * This class contains method to compare two API objects.
+ * The differences are stored in an APIDiff object.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+public class APIComparator {
+
+    /** 
+     * Top-level object representing the differences between two APIs. 
+     * It is this object which is used to generate the report later on.
+     */
+    public APIDiff apiDiff;
+
+    /** 
+     * Package-level object representing the differences between two packages. 
+     * This object is also used to determine which file to write documentation
+     * differences into.
+     */
+    public PackageDiff pkgDiff;
+
+    /** Default constructor. */
+    public APIComparator() {
+        apiDiff = new APIDiff();
+    }   
+
+    /** For easy local access to the old API object. */
+    private static API oldAPI_;
+    /** For easy local access to the new API object. */
+    private static API newAPI_;
+
+    /** 
+     * Compare two APIs. 
+     */
+    public void compareAPIs(API oldAPI, API newAPI) {
+        System.out.println("JDiff: comparing the old and new APIs ...");
+        oldAPI_ = oldAPI;
+        newAPI_ = newAPI;
+
+        double differs = 0.0;
+
+        apiDiff.oldAPIName_ = oldAPI.name_;
+        apiDiff.newAPIName_ = newAPI.name_;
+
+        Collections.sort(oldAPI.packages_);
+        Collections.sort(newAPI.packages_);
+
+        // Find packages which were removed in the new API
+        Iterator iter = oldAPI.packages_.iterator();
+        while (iter.hasNext()) {
+            PackageAPI oldPkg = (PackageAPI)(iter.next());
+            // This search is looking for an *exact* match. This is true in
+            // all the *API classes.
+            int idx = Collections.binarySearch(newAPI.packages_, oldPkg);
+            if (idx < 0) {
+                // If there an instance of a package with the same name 
+                // in both the old and new API, then treat it as changed,
+                // rather than removed and added. There will never be more than
+                // one instance of a package with the same name in an API.
+                int existsNew = newAPI.packages_.indexOf(oldPkg);
+                if (existsNew != -1) {
+                    // Package by the same name exists in both APIs
+                    // but there has been some or other change.
+                    differs += 2.0 * comparePackages(oldPkg, (PackageAPI)(newAPI.packages_.get(existsNew)));
+                }  else {
+                    if (trace)
+                        System.out.println("Package " + oldPkg.name_ + " was removed");
+                    apiDiff.packagesRemoved.add(oldPkg);
+                    differs += 1.0;
+                }
+            } else {
+                // The package exists unchanged in name or doc, but may 
+                // differ in classes and their members, so it still needs to 
+                // be compared.
+                differs += 2.0 * comparePackages(oldPkg, (PackageAPI)(newAPI.packages_.get(idx)));
+            }
+        } // while (iter.hasNext())
+
+        // Find packages which were added or changed in the new API
+        iter = newAPI.packages_.iterator();
+        while (iter.hasNext()) {
+            PackageAPI newPkg = (PackageAPI)(iter.next());
+            int idx = Collections.binarySearch(oldAPI.packages_, newPkg);
+            if (idx < 0) {
+                // See comments above
+                int existsOld = oldAPI.packages_.indexOf(newPkg);
+                if (existsOld != -1) {
+                    // Don't mark a package as added or compare it 
+                    // if it was already marked as changed
+                } else {
+                    if (trace)
+                        System.out.println("Package " + newPkg.name_ + " was added");
+                    apiDiff.packagesAdded.add(newPkg);
+                    differs += 1.0;
+                }
+            } else {
+                // It will already have been compared above.
+            }
+        } // while (iter.hasNext())
+
+        // Now that the numbers of members removed and added are known
+        // we can deduce more information about changes.
+        MergeChanges.mergeRemoveAdd(apiDiff);
+
+// The percent change statistic reported for all elements in each API is  
+// defined recursively as follows:
+// 
+// %age change = 100 * (added + removed + 2*changed)
+//               -----------------------------------
+//               sum of public elements in BOTH APIs
+//
+// The definition ensures that if all classes are removed and all new classes
+// added, the change will be 100%.
+// Evaluation of the visibility of elements has already been done when the 
+// XML was written out.
+// Note that this doesn't count changes in the modifiers of classes and 
+// packages. Other changes in members are counted.
+        Long denom = new Long(oldAPI.packages_.size() + newAPI.packages_.size());
+        // This should never be zero because an API always has packages?
+        if (denom.intValue() == 0) {
+            System.out.println("Error: no packages found in the APIs.");
+            return;
+        }
+        if (trace)
+            System.out.println("Top level changes: " + differs + "/" + denom.intValue());
+        differs = (100.0 * differs)/denom.doubleValue();
+
+        // Some differences such as documentation changes are not tracked in 
+        // the difference statistic, so a value of 0.0 does not mean that there
+        // were no differences between the APIs.
+        apiDiff.pdiff = differs;
+        Double percentage = new Double(differs);
+        int approxPercentage = percentage.intValue();
+        if (approxPercentage == 0)
+            System.out.println(" Approximately " + percentage + "% difference between the APIs");
+        else
+            System.out.println(" Approximately " + approxPercentage + "% difference between the APIs");
+
+        Diff.closeDiffFile();
+    }   
+
+    /** 
+     * Compare two packages.
+     */
+    public double comparePackages(PackageAPI oldPkg, PackageAPI newPkg) {
+        if (trace)
+            System.out.println("Comparing old package " + oldPkg.name_ + 
+                               " and new package " + newPkg.name_);
+        pkgDiff = new PackageDiff(oldPkg.name_);
+        double differs = 0.0;
+
+        Collections.sort(oldPkg.classes_);
+        Collections.sort(newPkg.classes_);
+      
+        // Find classes which were removed in the new package
+        Iterator iter = oldPkg.classes_.iterator();
+        while (iter.hasNext()) {
+            ClassAPI oldClass = (ClassAPI)(iter.next());
+            // This search is looking for an *exact* match. This is true in
+            // all the *API classes.
+            int idx = Collections.binarySearch(newPkg.classes_, oldClass);
+            if (idx < 0) {
+                // If there an instance of a class with the same name 
+                // in both the old and new package, then treat it as changed,
+                // rather than removed and added. There will never be more than
+                // one instance of a class with the same name in a package.
+                int existsNew = newPkg.classes_.indexOf(oldClass);
+                if (existsNew != -1) {
+                    // Class by the same name exists in both packages
+                    // but there has been some or other change.
+                    differs += 2.0 * compareClasses(oldClass, (ClassAPI)(newPkg.classes_.get(existsNew)), pkgDiff);
+                }  else {
+                    if (trace)
+                        System.out.println("  Class " + oldClass.name_ + " was removed");
+                    pkgDiff.classesRemoved.add(oldClass);
+                    differs += 1.0;
+                }
+            } else {
+                // The class exists unchanged in name or modifiers, but may 
+                // differ in members, so it still needs to be compared.
+                differs += 2.0 * compareClasses(oldClass, (ClassAPI)(newPkg.classes_.get(idx)), pkgDiff);
+            }
+        } // while (iter.hasNext())
+
+        // Find classes which were added or changed in the new package
+        iter = newPkg.classes_.iterator();
+        while (iter.hasNext()) {
+            ClassAPI newClass = (ClassAPI)(iter.next());
+            int idx = Collections.binarySearch(oldPkg.classes_, newClass);
+            if (idx < 0) {
+                // See comments above
+                int existsOld = oldPkg.classes_.indexOf(newClass);
+                if (existsOld != -1) {
+                    // Don't mark a class as added or compare it 
+                    // if it was already marked as changed
+                } else {
+                    if (trace)
+                        System.out.println("  Class " + newClass.name_ + " was added");
+                    pkgDiff.classesAdded.add(newClass);
+                    differs += 1.0;
+                }
+            } else {
+                // It will already have been compared above.
+            }
+        } // while (iter.hasNext())
+
+        // Check if the only change was in documentation. Bug 472521.
+        boolean differsFlag = false;
+        if (docChanged(oldPkg.doc_, newPkg.doc_)) {
+            String link = "<a href=\"pkg_" + oldPkg.name_ + HTMLReportGenerator.reportFileExt + "\" class=\"hiddenlink\">";
+            String id = oldPkg.name_ + "!package";
+            String title = link + "Package <b>" + oldPkg.name_ + "</b></a>";
+            pkgDiff.documentationChange_ = Diff.saveDocDiffs(pkgDiff.name_, null, oldPkg.doc_, newPkg.doc_, id, title);
+            differsFlag = true;
+        }
+
+        // Only add to the parent Diff object if some difference has been found
+        if (differs != 0.0 || differsFlag) 
+            apiDiff.packagesChanged.add(pkgDiff);
+
+        Long denom = new Long(oldPkg.classes_.size() + newPkg.classes_.size());
+        // This should never be zero because a package always has classes?
+        if (denom.intValue() == 0) {
+            System.out.println("Warning: no classes found in the package " + oldPkg.name_);
+            return 0.0;
+        }
+        if (trace)
+            System.out.println("Package " + pkgDiff.name_ + " had a difference of " + differs + "/" + denom.intValue());
+        pkgDiff.pdiff = 100.0 * differs/denom.doubleValue();
+        return differs/denom.doubleValue();
+    } // comparePackages()
+
+    /** 
+     * Compare two classes. 
+     *
+     * Need to compare constructors, methods and fields.
+     */
+    public double compareClasses(ClassAPI oldClass, ClassAPI newClass, PackageDiff pkgDiff) {
+        if (trace)
+            System.out.println("  Comparing old class " + oldClass.name_ + 
+                               " and new class " + newClass.name_);
+        boolean differsFlag = false;
+        double differs = 0.0;
+        ClassDiff classDiff = new ClassDiff(oldClass.name_);
+        classDiff.isInterface_ = newClass.isInterface_; // Used in the report
+
+        // Track changes in modifiers - class or interface
+        if (oldClass.isInterface_ != newClass.isInterface_) {
+            classDiff.modifiersChange_  = "Changed from ";
+            if (oldClass.isInterface_)
+                classDiff.modifiersChange_ += "an interface to a class.";
+            else
+                classDiff.modifiersChange_ += "a class to an interface.";
+            differsFlag = true;
+        }
+        // Track changes in inheritance
+        String inheritanceChange = ClassDiff.diff(oldClass, newClass);
+        if (inheritanceChange != null) {
+            classDiff.inheritanceChange_ = inheritanceChange;
+            differsFlag = true;
+        }
+        // Abstract or not
+        if (oldClass.isAbstract_ != newClass.isAbstract_) {
+            String changeText = "";
+            if (oldClass.isAbstract_)
+                changeText += "Changed from abstract to non-abstract.";
+            else
+                changeText += "Changed from non-abstract to abstract.";
+            classDiff.addModifiersChange(changeText);
+            differsFlag = true;
+        }
+        // Track changes in documentation
+        if (docChanged(oldClass.doc_, newClass.doc_)) {
+            String fqName = pkgDiff.name_ + "." + classDiff.name_;
+            String link = "<a href=\"" + fqName + HTMLReportGenerator.reportFileExt + "\" class=\"hiddenlink\">";
+            String id = pkgDiff.name_ + "." + classDiff.name_ + "!class";
+            String title = link + "Class <b>" + classDiff.name_ + "</b></a>";
+            classDiff.documentationChange_ = Diff.saveDocDiffs(pkgDiff.name_,
+ classDiff.name_, oldClass.doc_, newClass.doc_, id, title);
+            differsFlag = true;
+        }
+        // All other modifiers
+        String modifiersChange = oldClass.modifiers_.diff(newClass.modifiers_);
+        if (modifiersChange != null) {
+            differsFlag = true;
+            if (modifiersChange.indexOf("Change from deprecated to undeprecated") != -1) {
+                System.out.println("JDiff: warning: change from deprecated to undeprecated for class " + pkgDiff.name_ + "." + newClass.name_);
+                
+            }
+        }
+        classDiff.addModifiersChange(modifiersChange);
+        
+        // Track changes in members
+        boolean differsCtors = 
+            compareAllCtors(oldClass, newClass, classDiff);
+        boolean differsMethods = 
+            compareAllMethods(oldClass, newClass, classDiff);
+        boolean differsFields = 
+            compareAllFields(oldClass, newClass, classDiff);
+        if (differsCtors || differsMethods || differsFields) 
+            differsFlag = true;
+        
+        if (trace) {
+            System.out.println("  Ctors differ? " + differsCtors + 
+                ", Methods differ? " + differsMethods + 
+                ", Fields differ? " + differsFields);
+        }
+
+        // Only add to the parent if some difference has been found
+        if (differsFlag) 
+            pkgDiff.classesChanged.add(classDiff);
+
+        // Get the numbers of affected elements from the classDiff object
+         differs = 
+            classDiff.ctorsRemoved.size() + classDiff.ctorsAdded.size() +
+            classDiff.ctorsChanged.size() +
+            classDiff.methodsRemoved.size() + classDiff.methodsAdded.size() +
+            classDiff.methodsChanged.size() +
+            classDiff.fieldsRemoved.size() + classDiff.fieldsAdded.size() +
+            classDiff.fieldsChanged.size();
+         Long denom = new Long(
+             oldClass.ctors_.size() + 
+             numLocalMethods(oldClass.methods_) + 
+             numLocalFields(oldClass.fields_) +
+             newClass.ctors_.size() + 
+             numLocalMethods(newClass.methods_) + 
+             numLocalFields(newClass.fields_));
+         if (denom.intValue() == 0) {
+             // This is probably a placeholder interface, but documentation
+             // or modifiers etc may have changed
+             if (differsFlag) {
+                 classDiff.pdiff = 0.0; // 100.0 is too much
+                 return 1.0;
+             } else {
+                 return 0.0;
+             }
+         }
+         // Handle the case where the only change is in documentation or
+         // the modifiers
+         if (differsFlag && differs == 0.0) {
+             differs = 1.0;
+         }
+         if (trace)
+             System.out.println("  Class " + classDiff.name_ + " had a difference of " + differs + "/" + denom.intValue());
+         classDiff.pdiff = 100.0 * differs/denom.doubleValue();
+         return differs/denom.doubleValue();
+    } // compareClasses()
+
+    /** 
+     * Compare all the constructors in two classes. 
+     *
+     * The compareTo method in the ConstructorAPI class acts only upon the type.
+     */
+    public boolean compareAllCtors(ClassAPI oldClass, ClassAPI newClass, 
+                                   ClassDiff classDiff) {
+        if (trace)
+            System.out.println("    Comparing constructors: #old " + 
+              oldClass.ctors_.size() + ", #new " + newClass.ctors_.size());
+        boolean differs = false;
+        boolean singleCtor = false; // Set if there is only one ctor
+        
+        Collections.sort(oldClass.ctors_);
+        Collections.sort(newClass.ctors_);
+      
+        // Find ctors which were removed in the new class
+        Iterator iter = oldClass.ctors_.iterator();
+        while (iter.hasNext()) {
+            ConstructorAPI oldCtor = (ConstructorAPI)(iter.next());
+            int idx = Collections.binarySearch(newClass.ctors_, oldCtor);
+            if (idx < 0) {
+                int oldSize = oldClass.ctors_.size();
+                int newSize = newClass.ctors_.size();
+                if (oldSize == 1 && oldSize == newSize) {
+                    // If there is one constructor in the oldClass and one
+                    // constructor in the new class, then mark it as changed
+                    MemberDiff memberDiff = new MemberDiff(oldClass.name_);
+                    memberDiff.oldType_ = oldCtor.type_;
+                    memberDiff.oldExceptions_ = oldCtor.exceptions_;
+                    ConstructorAPI newCtor  = (ConstructorAPI)(newClass.ctors_.get(0));
+                    memberDiff.newType_ = newCtor.type_;
+                    memberDiff.newExceptions_ = newCtor.exceptions_;
+                    // Track changes in documentation
+                    if (docChanged(oldCtor.doc_, newCtor.doc_)) {
+                        String type = memberDiff.newType_;
+                        if (type.compareTo("void") == 0)
+                            type = "";
+                        String fqName = pkgDiff.name_ + "." + classDiff.name_;
+                        String link1 = "<a href=\"" + fqName + HTMLReportGenerator.reportFileExt + "\" class=\"hiddenlink\">";
+                        String link2 = "<a href=\"" + fqName + HTMLReportGenerator.reportFileExt + "#" + fqName + ".ctor_changed(" + type + ")\" class=\"hiddenlink\">";
+                        String id = pkgDiff.name_ + "." + classDiff.name_ + ".ctor(" + HTMLReportGenerator.simpleName(type) + ")";
+                        String title = link1 + "Class <b>" + classDiff.name_ + 
+                            "</b></a>, " + link2 + "constructor <b>" + classDiff.name_ + "(" + HTMLReportGenerator.simpleName(type) + ")</b></a>";
+                        memberDiff.documentationChange_ = Diff.saveDocDiffs(
+                            pkgDiff.name_, classDiff.name_, oldCtor.doc_, newCtor.doc_, id, title);
+                    }
+                    String modifiersChange = oldCtor.modifiers_.diff(newCtor.modifiers_);
+                    if (modifiersChange != null && modifiersChange.indexOf("Change from deprecated to undeprecated") != -1) {
+                        System.out.println("JDiff: warning: change from deprecated to undeprecated for a constructor in class" + newClass.name_);
+                    }
+                    memberDiff.addModifiersChange(modifiersChange);
+                    if (trace)
+                        System.out.println("    The single constructor was changed");
+                    classDiff.ctorsChanged.add(memberDiff);
+                    singleCtor = true;
+                } else {
+                    if (trace)
+                        System.out.println("    Constructor " + oldClass.name_ + " was removed");
+                    classDiff.ctorsRemoved.add(oldCtor);
+                }
+                differs = true;
+            }
+        } // while (iter.hasNext())
+
+        // Find ctors which were added in the new class
+        iter = newClass.ctors_.iterator();
+        while (iter.hasNext()) {
+            ConstructorAPI newCtor = (ConstructorAPI)(iter.next());
+            int idx = Collections.binarySearch(oldClass.ctors_, newCtor);
+            if (idx < 0) {
+                if (!singleCtor) {
+                    if (trace)
+                        System.out.println("    Constructor " + oldClass.name_ + " was added");
+                    classDiff.ctorsAdded.add(newCtor);
+                    differs = true;
+                }
+            }
+        } // while (iter.hasNext())
+
+        return differs;
+    } // compareAllCtors()
+
+    /** 
+     * Compare all the methods in two classes. 
+     *
+     * We have to deal with the cases where:
+     *  - there is only one method with a given name, but its signature changes
+     *  - there is more than one method with the same name, and some of them 
+     *    may have signature changes
+     * The simplest way to deal with this is to make the MethodAPI comparator
+     * check the params and return type, as well as the name. This means that
+     * changing a parameter's type would cause the method to be seen as 
+     * removed and added. To avoid this for the simple case, check for before 
+     * recording a method as removed or added.
+     */
+    public boolean compareAllMethods(ClassAPI oldClass, ClassAPI newClass, ClassDiff classDiff) {
+        if (trace)
+            System.out.println("    Comparing methods: #old " + 
+                               oldClass.methods_.size() + ", #new " +
+                               newClass.methods_.size());
+        boolean differs = false;
+        
+        Collections.sort(oldClass.methods_);
+        Collections.sort(newClass.methods_);
+      
+        // Find methods which were removed in the new class
+        Iterator iter = oldClass.methods_.iterator();
+        while (iter.hasNext()) {
+            MethodAPI oldMethod = (MethodAPI)(iter.next());
+            int idx = -1;
+            MethodAPI[] methodArr = new MethodAPI[newClass.methods_.size()];
+            methodArr = (MethodAPI[])newClass.methods_.toArray(methodArr);
+            for (int methodIdx = 0; methodIdx < methodArr.length; methodIdx++) {
+                MethodAPI newMethod = methodArr[methodIdx];
+                if (oldMethod.compareTo(newMethod) == 0) {
+                    idx  = methodIdx;
+                    break;
+                }
+            }
+// NOTE: there was a problem with the binarySearch for 
+// java.lang.Byte.toString(byte b) returning -16 when the compareTo method
+// returned 0 on entry 13. Changed to use arrays instead, so maybe it was
+// an issue with methods having another List of params used indirectly by 
+// compareTo(), unlike constructors and fields?
+//            int idx = Collections.binarySearch(newClass.methods_, oldMethod);
+            if (idx < 0) {
+                // If there is only one instance of a method with this name 
+                // in both the old and new class, then treat it as changed,
+                // rather than removed and added.
+                // Find how many instances of this method name there are in
+                // the old and new class. The equals comparator is just on 
+                // the method name.
+                int startOld = oldClass.methods_.indexOf(oldMethod); 
+                int endOld = oldClass.methods_.lastIndexOf(oldMethod);
+                int startNew = newClass.methods_.indexOf(oldMethod); 
+                int endNew = newClass.methods_.lastIndexOf(oldMethod);
+
+                if (startOld != -1 && startOld == endOld && 
+                    startNew != -1 && startNew == endNew) {
+                    MethodAPI newMethod = (MethodAPI)(newClass.methods_.get(startNew));
+                    // Only one method with that name exists in both packages,
+                    // so it is valid to compare the two methods. We know it 
+                    // has changed, because the binarySearch did not find it.
+                    if (oldMethod.inheritedFrom_ == null || 
+                        newMethod.inheritedFrom_ == null) {
+                        // We also know that at least one of the methods is 
+                        // locally defined.
+                        compareMethods(oldMethod, newMethod, classDiff);
+                        differs = true;
+                    }
+                } else if (oldMethod.inheritedFrom_ == null) {
+                    // Only concerned with locally defined methods
+                    if (trace)
+                        System.out.println("    Method " + oldMethod.name_ + 
+                                           "(" + oldMethod.getSignature() + 
+                                           ") was removed");
+                    classDiff.methodsRemoved.add(oldMethod);
+                    differs = true;
+                }
+            }
+        } // while (iter.hasNext())
+
+        // Find methods which were added in the new class
+        iter = newClass.methods_.iterator();
+        while (iter.hasNext()) {
+            MethodAPI newMethod = (MethodAPI)(iter.next());
+            // Only concerned with locally defined methods
+            if (newMethod.inheritedFrom_ != null)
+                continue;
+            int idx = -1;
+            MethodAPI[] methodArr = new MethodAPI[oldClass.methods_.size()];
+            methodArr = (MethodAPI[])oldClass.methods_.toArray(methodArr);
+            for (int methodIdx = 0; methodIdx < methodArr.length; methodIdx++) {
+                MethodAPI oldMethod = methodArr[methodIdx];
+                if (newMethod.compareTo(oldMethod) == 0) {
+                    idx  = methodIdx;
+                    break;
+                }
+            }
+// See note above about searching an array instead of binarySearch
+//            int idx = Collections.binarySearch(oldClass.methods_, newMethod);
+            if (idx < 0) {
+                // See comments above
+                int startOld = oldClass.methods_.indexOf(newMethod); 
+                int endOld = oldClass.methods_.lastIndexOf(newMethod);
+                int startNew = newClass.methods_.indexOf(newMethod); 
+                int endNew = newClass.methods_.lastIndexOf(newMethod);
+
+                if (startOld != -1 && startOld == endOld && 
+                    startNew != -1 && startNew == endNew) {
+                    // Don't mark a method as added if it was marked as changed
+                    // The comparison will have been done just above here.
+                } else {
+                    if (trace)
+                        System.out.println("    Method " + newMethod.name_ + 
+                                           "(" + newMethod.getSignature() + ") was added");
+                    classDiff.methodsAdded.add(newMethod);
+                    differs = true;
+                }
+            }
+        } // while (iter.hasNext())
+
+        return differs;
+    } // compareAllMethods()
+
+    /** 
+     * Compare two methods which have the same name. 
+     */
+    public boolean compareMethods(MethodAPI oldMethod, MethodAPI newMethod, ClassDiff classDiff) {
+        MemberDiff methodDiff = new MemberDiff(oldMethod.name_);
+        boolean differs = false;
+        // Check changes in return type
+        methodDiff.oldType_ = oldMethod.returnType_;
+        methodDiff.newType_ = newMethod.returnType_;
+        if (oldMethod.returnType_.compareTo(newMethod.returnType_) != 0) {
+            differs = true;
+        }
+        // Check changes in signature
+        String oldSig = oldMethod.getSignature();
+        String newSig = newMethod.getSignature();
+        methodDiff.oldSignature_ = oldSig;
+        methodDiff.newSignature_ = newSig;
+        if (oldSig.compareTo(newSig) != 0) {
+            differs = true;
+        }
+        // Changes in inheritance
+        int inh = changedInheritance(oldMethod.inheritedFrom_, newMethod.inheritedFrom_);
+        if (inh != 0)
+            differs = true;
+        if (inh == 1) {
+            methodDiff.addModifiersChange("Method was locally defined, but is now inherited from " + linkToClass(newMethod, true) + ".");
+            methodDiff.inheritedFrom_ = newMethod.inheritedFrom_;
+        } else if (inh == 2) {
+            methodDiff.addModifiersChange("Method was inherited from " + linkToClass(oldMethod, false) + ", but is now defined locally.");
+        } else if (inh == 3) {
+            methodDiff.addModifiersChange("Method was inherited from " + 
+                                          linkToClass(oldMethod, false) + ", and is now inherited from " + linkToClass(newMethod, true) + ".");
+            methodDiff.inheritedFrom_ = newMethod.inheritedFrom_;
+        }
+        // Abstract or not
+        if (oldMethod.isAbstract_ != newMethod.isAbstract_) {
+            String changeText = "";
+            if (oldMethod.isAbstract_)
+                changeText += "Changed from abstract to non-abstract.";
+            else
+                changeText += "Changed from non-abstract to abstract.";
+            methodDiff.addModifiersChange(changeText);
+            differs = true;
+        }
+        // Native or not
+        if (Diff.showAllChanges && 
+	    oldMethod.isNative_ != newMethod.isNative_) {
+            String changeText = "";
+            if (oldMethod.isNative_)
+                changeText += "Changed from native to non-native.";
+            else
+                changeText += "Changed from non-native to native.";
+            methodDiff.addModifiersChange(changeText);
+            differs = true;
+        }
+        // Synchronized or not
+        if (Diff.showAllChanges && 
+	    oldMethod.isSynchronized_ != newMethod.isSynchronized_) {
+            String changeText = "";
+            if (oldMethod.isSynchronized_)
+                changeText += "Changed from synchronized to non-synchronized.";
+            else
+                changeText += "Changed from non-synchronized to synchronized.";
+            methodDiff.addModifiersChange(changeText);
+            differs = true;
+        }
+
+        // Check changes in exceptions thrown
+        methodDiff.oldExceptions_ = oldMethod.exceptions_;
+        methodDiff.newExceptions_ = newMethod.exceptions_;
+        if (oldMethod.exceptions_.compareTo(newMethod.exceptions_) != 0) {
+            differs = true;
+        }
+
+        // Track changes in documentation
+        if (docChanged(oldMethod.doc_, newMethod.doc_)) {
+            String sig = methodDiff.newSignature_;
+            if (sig.compareTo("void") == 0)
+                sig = "";
+            String fqName = pkgDiff.name_ + "." + classDiff.name_;
+            String link1 = "<a href=\"" + fqName + HTMLReportGenerator.reportFileExt + "\" class=\"hiddenlink\">";
+            String link2 = "<a href=\"" + fqName + HTMLReportGenerator.reportFileExt + "#" + fqName + "." + newMethod.name_ + "_changed(" + sig + ")\" class=\"hiddenlink\">";
+            String id = pkgDiff.name_ + "." + classDiff.name_ + ".dmethod." + newMethod.name_ + "(" + HTMLReportGenerator.simpleName(sig) + ")";
+            String title = link1 + "Class <b>" + classDiff.name_ + "</b></a>, " +
+                link2 + HTMLReportGenerator.simpleName(methodDiff.newType_) + " <b>" + newMethod.name_ + "(" + HTMLReportGenerator.simpleName(sig) + ")</b></a>";
+            methodDiff.documentationChange_ = Diff.saveDocDiffs(pkgDiff.name_, classDiff.name_, oldMethod.doc_, newMethod.doc_, id, title);
+            differs = true;
+        }
+
+        // All other modifiers
+        String modifiersChange = oldMethod.modifiers_.diff(newMethod.modifiers_);
+        if (modifiersChange != null) {
+            differs = true;
+            if (modifiersChange.indexOf("Change from deprecated to undeprecated") != -1) {
+                System.out.println("JDiff: warning: change from deprecated to undeprecated for method " +  classDiff.name_ + "." + newMethod.name_);
+                
+            }
+        }
+        methodDiff.addModifiersChange(modifiersChange);
+
+        // Only add to the parent if some difference has been found
+        if (differs) {
+            if (trace) {
+                System.out.println("    Method " + newMethod.name_ + 
+                    " was changed: old: " + 
+                   oldMethod.returnType_ + "(" + oldSig + "), new: " +
+                   newMethod.returnType_ + "(" + newSig + ")");
+                if (methodDiff.modifiersChange_ != null)
+                    System.out.println("    Modifier change: " + methodDiff.modifiersChange_);
+            }
+            classDiff.methodsChanged.add(methodDiff);
+        }
+
+        return differs;
+    } // compareMethods()
+
+    /** 
+     * Compare all the fields in two classes. 
+     */
+    public boolean compareAllFields(ClassAPI oldClass, ClassAPI newClass, 
+                                    ClassDiff classDiff) {
+        if (trace)
+            System.out.println("    Comparing fields: #old " + 
+                               oldClass.fields_.size() + ", #new " 
+                               + newClass.fields_.size());
+        boolean differs = false;
+        
+        Collections.sort(oldClass.fields_);
+        Collections.sort(newClass.fields_);
+      
+        // Find fields which were removed in the new class
+        Iterator iter = oldClass.fields_.iterator();
+        while (iter.hasNext()) {
+            FieldAPI oldField = (FieldAPI)(iter.next());
+            int idx = Collections.binarySearch(newClass.fields_, oldField);
+            if (idx < 0) {
+                // If there an instance of a field with the same name 
+                // in both the old and new class, then treat it as changed,
+                // rather than removed and added. There will never be more than
+                // one instance of a field with the same name in a class.
+                int existsNew = newClass.fields_.indexOf(oldField);
+                if (existsNew != -1) {
+                    FieldAPI newField = (FieldAPI)(newClass.fields_.get(existsNew));
+                    if (oldField.inheritedFrom_ == null || 
+                        newField.inheritedFrom_ == null) {
+                        // We also know that one of the fields is locally defined.
+                        MemberDiff memberDiff = new MemberDiff(oldField.name_);
+                        memberDiff.oldType_ = oldField.type_;
+                        memberDiff.newType_ = newField.type_;
+                        // Changes in inheritance
+                        int inh = changedInheritance(oldField.inheritedFrom_, newField.inheritedFrom_);
+                        if (inh != 0)
+                            differs = true;
+                        if (inh == 1) {
+                            memberDiff.addModifiersChange("Field was locally defined, but is now inherited from " + linkToClass(newField, true) + ".");
+                            memberDiff.inheritedFrom_ = newField.inheritedFrom_;
+                        } else if (inh == 2) {
+                            memberDiff.addModifiersChange("Field was inherited from " + linkToClass(oldField, false) + ", but is now defined locally.");
+                        } else if (inh == 3) {
+                            memberDiff.addModifiersChange("Field was inherited from " + linkToClass(oldField, false) + ", and is now inherited from " + linkToClass(newField, true) + ".");
+                            memberDiff.inheritedFrom_ = newField.inheritedFrom_;
+                        }
+                        // Transient or not
+                        if (oldField.isTransient_ != newField.isTransient_) {
+                            String changeText = "";
+                            if (oldField.isTransient_)
+                                changeText += "Changed from transient to non-transient.";
+                            else
+                                changeText += "Changed from non-transient to transient.";
+                            memberDiff.addModifiersChange(changeText);
+                            differs = true;
+                        }
+                        // Volatile or not
+                        if (oldField.isVolatile_ != newField.isVolatile_) {
+                            String changeText = "";
+                            if (oldField.isVolatile_)
+                                changeText += "Changed from volatile to non-volatile.";
+                            else
+                                changeText += "Changed from non-volatile to volatile.";
+                            memberDiff.addModifiersChange(changeText);
+                            differs = true;
+                        }
+                        // Change in value of the field
+                        if (oldField.value_ != null &&
+                            newField.value_ != null &&
+                            oldField.value_.compareTo(newField.value_) != 0) {
+                            String changeText = "Changed in value from " + oldField.value_
+                                + " to " + newField.value_ +".";
+                            memberDiff.addModifiersChange(changeText);
+                            differs = true;
+                        }
+                        // Track changes in documentation
+                        if (docChanged(oldField.doc_, newField.doc_)) {
+                            String fqName = pkgDiff.name_ + "." + classDiff.name_;
+                            String link1 = "<a href=\"" + fqName + HTMLReportGenerator.reportFileExt + "\" class=\"hiddenlink\">";
+                            String link2 = "<a href=\"" + fqName + HTMLReportGenerator.reportFileExt + "#" + fqName + "." + newField.name_ + "\" class=\"hiddenlink\">";
+                            String id = pkgDiff.name_ + "." + classDiff.name_ + ".field." + newField.name_;
+                            String title = link1 + "Class <b>" + classDiff.name_ + "</b></a>, " +
+                                link2 + HTMLReportGenerator.simpleName(memberDiff.newType_) + " <b>" + newField.name_ + "</b></a>";
+                            memberDiff.documentationChange_ = Diff.saveDocDiffs(pkgDiff.name_, classDiff.name_, oldField.doc_, newField.doc_, id, title);
+                            differs = true;
+                        }
+                        
+                        // Other differences
+                        String modifiersChange = oldField.modifiers_.diff(newField.modifiers_);
+                        memberDiff.addModifiersChange(modifiersChange);
+                        if (modifiersChange != null && modifiersChange.indexOf("Change from deprecated to undeprecated") != -1) {
+                            System.out.println("JDiff: warning: change from deprecated to undeprecated for class " + newClass.name_ + ", field " + newField.name_);
+                        }
+                        if (trace)
+                            System.out.println("    Field " + newField.name_ + " was changed");
+                        classDiff.fieldsChanged.add(memberDiff);
+                        differs = true;
+                    }
+                } else if (oldField.inheritedFrom_ == null) {
+                    if (trace)
+                        System.out.println("    Field " + oldField.name_ + " was removed");
+                    classDiff.fieldsRemoved.add(oldField);
+                    differs = true;
+                }
+            }
+        } // while (iter.hasNext())
+
+        // Find fields which were added in the new class
+        iter = newClass.fields_.iterator();
+        while (iter.hasNext()) {
+            FieldAPI newField = (FieldAPI)(iter.next());
+            // Only concerned with locally defined fields
+            if (newField.inheritedFrom_ != null)
+                continue;
+            int idx = Collections.binarySearch(oldClass.fields_, newField);
+            if (idx < 0) {
+                // See comments above
+                int existsOld = oldClass.fields_.indexOf(newField);
+                if (existsOld != -1) {
+                    // Don't mark a field as added if it was marked as changed
+                } else {
+                    if (trace)
+                        System.out.println("    Field " + newField.name_ + " was added");
+                    classDiff.fieldsAdded.add(newField);
+                    differs = true;
+                }
+            }
+        } // while (iter.hasNext())
+
+        return differs;
+    } // compareFields()
+
+    /** 
+     * Decide if two blocks of documentation changed. 
+     *
+     * @return true if both are non-null and differ, 
+     *              or if one is null and the other is not.
+     */
+    public static boolean docChanged(String oldDoc, String newDoc) {
+        if (!HTMLReportGenerator.reportDocChanges)
+            return false; // Don't even count doc changes as changes
+        if (oldDoc == null && newDoc != null)
+            return true;
+        if (oldDoc != null && newDoc == null)
+            return true;
+        if (oldDoc != null && newDoc != null && oldDoc.compareTo(newDoc) != 0)
+            return true;
+        return false;
+    }
+
+    /** 
+     * Decide if two elements changed where they were defined. 
+     *
+     * @return 0 if both are null, or both are non-null and are the same.
+     *         1 if the oldInherit was null and newInherit is non-null.
+     *         2 if the oldInherit was non-null and newInherit is null.
+     *         3 if the oldInherit was non-null and newInherit is non-null 
+     *           and they differ.
+     */
+    public static int changedInheritance(String oldInherit, String newInherit) {
+        if (oldInherit == null && newInherit == null)
+            return 0;
+        if (oldInherit == null && newInherit != null)
+            return 1;
+        if (oldInherit != null && newInherit == null)
+            return 2;
+        if (oldInherit.compareTo(newInherit) == 0)
+            return 0;
+        else
+            return 3;
+    }
+
+    /** 
+     * Generate a link to the Javadoc page for the given method.
+     */
+    public static String linkToClass(MethodAPI m, boolean useNew) {
+        String sig = m.getSignature();
+        if (sig.compareTo("void") == 0)
+            sig = "";
+        return linkToClass(m.inheritedFrom_, m.name_, sig, useNew);
+    }
+
+    /** 
+     * Generate a link to the Javadoc page for the given field.
+     */
+    public static String linkToClass(FieldAPI m, boolean useNew) {
+        return linkToClass(m.inheritedFrom_, m.name_, null, useNew);
+    }
+
+    /** 
+     * Given the name of the class, generate a link to a relevant page.
+     * This was originally for inheritance changes, so the JDiff page could 
+     * be a class changes page, or a section in a removed or added classes 
+     * table. Since there was no easy way to tell which type the link
+     * should be, it is now just a link to the relevant Javadoc page.
+     */
+    public static String linkToClass(String className, String memberName, 
+                                     String memberType, boolean useNew) {
+        if (!useNew && HTMLReportGenerator.oldDocPrefix == null) {
+            return "<tt>" + className + "</tt>"; // No link possible
+        }
+        API api = oldAPI_;
+        String prefix = HTMLReportGenerator.oldDocPrefix;
+        if (useNew) {
+            api = newAPI_;
+            prefix = HTMLReportGenerator.newDocPrefix;
+        }
+        ClassAPI cls = (ClassAPI)api.classes_.get(className);
+        if (cls == null) {
+            if (useNew)
+                System.out.println("Warning: class " + className + " not found in the new API when creating Javadoc link");
+            else
+                System.out.println("Warning: class " + className + " not found in the old API when creating Javadoc link");
+            return "<tt>" + className + "</tt>";
+        }
+        int clsIdx = className.indexOf(cls.name_);
+        if (clsIdx != -1) {
+            String pkgRef = className.substring(0, clsIdx);
+            pkgRef = pkgRef.replace('.', '/');
+            String res = "<a href=\"" + prefix + pkgRef + cls.name_ + ".html#" + memberName;
+            if (memberType != null)
+                res += "(" + memberType + ")";
+            res += "\" target=\"_top\">" + "<tt>" + cls.name_ + "</tt></a>";
+            return res;
+        }
+        return "<tt>" + className + "</tt>";
+    }    
+
+    /** 
+     * Return the number of methods which are locally defined.
+     */
+    public int numLocalMethods(List methods) {
+        int res = 0;
+        Iterator iter = methods.iterator();
+        while (iter.hasNext()) {
+            MethodAPI m = (MethodAPI)(iter.next());
+            if (m.inheritedFrom_ == null) 
+                res++;
+        }
+        return res;
+    }
+
+    /** 
+     * Return the number of fields which are locally defined.
+     */
+    public int numLocalFields(List fields) {
+        int res = 0;
+        Iterator iter = fields.iterator();
+        while (iter.hasNext()) {
+            FieldAPI f = (FieldAPI)(iter.next());
+            if (f.inheritedFrom_ == null) 
+                res++;
+        }
+        return res;
+    }
+
+    /** Set to enable increased logging verbosity for debugging. */
+    private boolean trace = false;
+}
diff --git a/src/jdiff/APIDiff.java b/src/jdiff/APIDiff.java
new file mode 100755
index 0000000..4b4fd26
--- /dev/null
+++ b/src/jdiff/APIDiff.java
@@ -0,0 +1,40 @@
+package jdiff;
+
+import java.util.*;
+import com.sun.javadoc.*;
+
+/**
+ * The class contains the changes between two API objects; packages added,
+ * removed and changed. The packages are represented by PackageDiff objects,
+ * which contain the changes in each package, and so on.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+public class APIDiff {
+
+    /** Packages added in the new API. */
+    public List packagesAdded = null; // PackageAPI[]
+    /** Packages removed in the new API. */
+    public List packagesRemoved = null; // PackageAPI[]
+    /** Packages changed in the new API. */
+    public List packagesChanged = null; // PackageDiff[]
+
+    /** Name of the old API. */
+    public static String oldAPIName_;
+    /** Name of the old API. */
+    public static String newAPIName_;
+
+    /* The overall percentage difference between the two APIs. */
+    public double pdiff = 0.0;
+
+    /** Default constructor. */
+    public APIDiff() {
+        oldAPIName_ = null;
+        newAPIName_ = null;
+        packagesAdded = new ArrayList(); // PackageAPI[]
+        packagesRemoved = new ArrayList(); // PackageAPI[]
+        packagesChanged = new ArrayList(); // PackageDiff[]
+    }   
+}
+
diff --git a/src/jdiff/APIHandler.java b/src/jdiff/APIHandler.java
new file mode 100755
index 0000000..be1a6fc
--- /dev/null
+++ b/src/jdiff/APIHandler.java
@@ -0,0 +1,362 @@
+package jdiff;
+
+import java.io.*;
+import java.util.*;
+
+/* For SAX parsing in APIHandler */
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Handle the parsing of an XML file and the generation of an API object.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+class APIHandler extends DefaultHandler {
+
+    /** The API object which is populated from the XML file. */
+    public API api_;
+
+    /** Default constructor. */
+    public APIHandler(API api, boolean createGlobalComments) {
+        api_ = api;
+        createGlobalComments_ = createGlobalComments;
+        tagStack = new LinkedList();
+    }   
+
+    /** If set, then check that each comment is a sentence. */
+    public static boolean checkIsSentence = false;
+
+    /** 
+     * Contains the name of the current package element type
+     * where documentation is being added. Also used as the level
+     * at which to add documentation into an element, i.e. class-level
+     * or package-level.
+     */
+    private String currentElement = null;
+
+    /** If set, then create the global list of comments. */
+    private boolean createGlobalComments_ = false;
+
+    /** Set if inside a doc element. */
+    private boolean inDoc = false;
+
+    /** The current comment text being assembled. */
+    private String currentText = null;
+
+    /** The current text from deprecation, null if empty. */
+    private String currentDepText = null;
+
+    /** 
+     * The stack of SingleComment objects awaiting the comment text 
+     * currently being assembled. 
+     */
+    private LinkedList tagStack = null;
+
+    /** Called at the start of the document. */
+    public void startDocument() {
+    }
+    
+    /** Called when the end of the document is reached. */
+    public void endDocument() {
+        if (trace)
+            api_.dump();
+        System.out.println(" finished");
+    }
+
+    /** Called when a new element is started. */
+    public void startElement(java.lang.String uri, java.lang.String localName,
+                             java.lang.String qName, Attributes attributes) {
+	 // The change to JAXP compliance produced this change.
+	if (localName.equals(""))
+	    localName = qName;
+        if (localName.compareTo("api") == 0) {
+            String apiName = attributes.getValue("name");
+            String version = attributes.getValue("jdversion"); // Not used yet
+            XMLToAPI.nameAPI(apiName);
+        } else if (localName.compareTo("package") == 0) {
+            currentElement = localName;
+            String pkgName = attributes.getValue("name");
+            XMLToAPI.addPackage(pkgName);
+        } else if (localName.compareTo("class") == 0) {
+            currentElement = localName;
+            String className = attributes.getValue("name");
+            String parentName = attributes.getValue("extends");
+            boolean isAbstract = false;
+            if (attributes.getValue("abstract").compareTo("true") == 0)
+                isAbstract = true;
+            XMLToAPI.addClass(className, parentName, isAbstract, getModifiers(attributes));
+        } else if (localName.compareTo("interface") == 0) {
+            currentElement = localName;
+            String className = attributes.getValue("name");
+            String parentName = attributes.getValue("extends");
+            boolean isAbstract = false;
+            if (attributes.getValue("abstract").compareTo("true") == 0)
+                isAbstract = true;
+            XMLToAPI.addInterface(className, parentName, isAbstract, getModifiers(attributes));
+        } else if (localName.compareTo("implements") == 0) {
+            String interfaceName = attributes.getValue("name");
+            XMLToAPI.addImplements(interfaceName);
+        } else if (localName.compareTo("constructor") == 0) {
+            currentElement = localName;
+            String ctorType = attributes.getValue("type");
+            XMLToAPI.addCtor(ctorType, getModifiers(attributes));
+        } else if (localName.compareTo("method") == 0) {
+            currentElement = localName;
+            String methodName = attributes.getValue("name");
+            String returnType = attributes.getValue("return");
+            boolean isAbstract = false;
+            if (attributes.getValue("abstract").compareTo("true") == 0)
+                isAbstract = true;
+            boolean isNative = false;
+            if (attributes.getValue("native").compareTo("true") == 0)
+                isNative = true;
+            boolean isSynchronized = false;
+            if (attributes.getValue("synchronized").compareTo("true") == 0)
+                isSynchronized = true;
+            XMLToAPI.addMethod(methodName, returnType, isAbstract, isNative, 
+                               isSynchronized, getModifiers(attributes));
+        } else if (localName.compareTo("field") == 0) {
+            currentElement = localName;
+            String fieldName = attributes.getValue("name");
+            String fieldType = attributes.getValue("type");
+            boolean isTransient = false;
+            if (attributes.getValue("transient").compareTo("true") == 0)
+                isTransient = true;
+            boolean isVolatile = false;
+            if (attributes.getValue("volatile").compareTo("true") == 0)
+                isVolatile = true;
+            String value = attributes.getValue("value");
+            XMLToAPI.addField(fieldName, fieldType, isTransient, isVolatile, 
+                              value, getModifiers(attributes));
+        } else if (localName.compareTo("param") == 0) {
+            String paramName = attributes.getValue("name");
+            String paramType = attributes.getValue("type");
+            XMLToAPI.addParam(paramName, paramType);
+        } else if (localName.compareTo("exception") == 0) {
+            String paramName = attributes.getValue("name");
+            String paramType = attributes.getValue("type");
+            XMLToAPI.addException(paramName, paramType, currentElement);
+        } else if (localName.compareTo("doc") == 0) {
+            inDoc = true;
+            currentText = null;
+        } else {
+            if (inDoc) {
+                // Start of an element, probably an HTML element
+                addStartTagToText(localName, attributes);
+            } else {
+                System.out.println("Error: unknown element type: " + localName);
+                System.exit(-1);
+            }
+        }
+    }
+    
+    /** Called when the end of an element is reached. */
+    public void endElement(java.lang.String uri, java.lang.String localName, 
+                           java.lang.String qName) {
+	if (localName.equals(""))
+	    localName = qName;
+        // Deal with the end of doc blocks
+        if (localName.compareTo("doc") == 0) {
+            inDoc = false;
+            // Add the assembled comment text to the appropriate current
+            // program element, as determined by currentElement.
+            addTextToComments();
+        } else if (inDoc) {
+            // An element was found inside the HTML text
+            addEndTagToText(localName);
+        } else if (currentElement.compareTo("constructor") == 0 && 
+                   localName.compareTo("constructor") == 0) {
+            currentElement = "class";
+        } else if (currentElement.compareTo("method") == 0 && 
+                   localName.compareTo("method") == 0) {
+            currentElement = "class";
+        } else if (currentElement.compareTo("field") == 0 && 
+                   localName.compareTo("field") == 0) {
+            currentElement = "class";
+        } else if (currentElement.compareTo("class") == 0 ||
+                   currentElement.compareTo("interface") == 0) {
+            // Feature request 510307 and bug 517383: duplicate comment ids.
+            // The end of a member element leaves the currentElement at the 
+            // "class" level, but the next class may in fact be an interface
+            // and so the currentElement here will be "interface".
+            if (localName.compareTo("class") == 0 || 
+                localName.compareTo("interface") == 0) {
+                currentElement = "package";
+            }
+        }
+    }
+
+    /** Called to process text. */
+    public void characters(char[] ch, int start, int length) {
+         if (inDoc) {
+            String chunk = new String(ch, start, length);
+            if (currentText == null)
+                currentText = chunk;
+            else
+                currentText += chunk;
+         }
+    }
+
+    /** 
+     * Trim the current text, check it is a sentence and add it to the
+     * current program element. 
+     */
+    public void addTextToComments() {
+        // Eliminate any whitespace at each end of the text.
+        currentText = currentText.trim();        
+        // Convert any @link tags to HTML links.
+        if (convertAtLinks) {
+            currentText = Comments.convertAtLinks(currentText, currentElement, 
+                                                  api_.currPkg_, api_.currClass_);
+        }
+        // Check that it is a sentence
+        if (checkIsSentence && !currentText.endsWith(".") && 
+            currentText.compareTo(Comments.placeHolderText) != 0) {
+            System.out.println("Warning: text of comment does not end in a period: " + currentText);
+        }
+        // The construction of the commentID assumes that the 
+        // documentation is the final element to be parsed. The format matches
+        // the format used in the report generator to look up comments in the
+        // the existingComments object.
+        String commentID = null;
+        // Add this comment to the current API element.
+        if (currentElement.compareTo("package") == 0) {
+            api_.currPkg_.doc_ = currentText;
+            commentID = api_.currPkg_.name_;
+        } else if (currentElement.compareTo("class") == 0 ||
+                   currentElement.compareTo("interface") == 0) {
+            api_.currClass_.doc_ = currentText;
+            commentID = api_.currPkg_.name_ + "." + api_.currClass_.name_;
+        } else if (currentElement.compareTo("constructor") == 0) {
+            api_.currCtor_.doc_ = currentText;
+            commentID = api_.currPkg_.name_ + "." + api_.currClass_.name_ +
+                ".ctor_changed(";
+            if (api_.currCtor_.type_.compareTo("void") == 0)
+                commentID = commentID + ")";
+            else
+                commentID = commentID + api_.currCtor_.type_ + ")";
+        } else if (currentElement.compareTo("method") == 0) {
+            api_.currMethod_.doc_ = currentText;
+            commentID = api_.currPkg_.name_ + "." + api_.currClass_.name_ +
+                "." + api_.currMethod_.name_ + "_changed(" + 
+                api_.currMethod_.getSignature() + ")";
+        } else if (currentElement.compareTo("field") == 0) {
+            api_.currField_.doc_ = currentText;
+            commentID = api_.currPkg_.name_ + "." + api_.currClass_.name_ +
+                "." + api_.currField_.name_;
+        }            
+        // Add to the list of possible comments for use when an
+        // element has changed (not removed or added).
+        if (createGlobalComments_ && commentID != null) {
+            String ct = currentText;
+            // Use any deprecation text as the possible comment, ignoring 
+            // any other comment text.
+            if (currentDepText != null) {
+                ct = currentDepText;
+                currentDepText = null; // Never reuse it. Bug 469794
+            }
+            String ctOld = (String)(Comments.allPossibleComments.put(commentID, ct));
+            if (ctOld != null) {
+                System.out.println("Error: duplicate comment id: " + commentID);
+                System.exit(5);
+            }
+        }
+    }
+
+    /** 
+     * Add the start tag to the current comment text. 
+     */
+    public void addStartTagToText(String localName, Attributes attributes) {
+        // Need to insert the HTML tag into the current text
+        String currentHTMLTag = localName;
+        // Save the tag in a stack
+        tagStack.add(currentHTMLTag);
+        String tag = "<" + currentHTMLTag;
+        // Now add all the attributes into the current text
+        int len = attributes.getLength();
+        for (int i = 0; i < len; i++) {
+            String name = attributes.getLocalName(i);
+            String value = attributes.getValue(i);
+            tag += " " + name + "=\"" + value+ "\"";
+        }
+
+        // End the tag
+        if (Comments.isMinimizedTag(currentHTMLTag)) {
+            tag += "/>";
+        } else {
+            tag += ">";
+        }
+        // Now insert the HTML tag into the current text
+        if (currentText == null)
+            currentText = tag;
+        else
+            currentText += tag;
+    }
+
+    /** 
+     * Add the end tag to the current comment text. 
+     */
+    public void addEndTagToText(String localName) {
+        // Close the current HTML tag
+        String currentHTMLTag = (String)(tagStack.removeLast());
+        if (!Comments.isMinimizedTag(currentHTMLTag))
+            currentText += "</" + currentHTMLTag + ">";
+    }
+
+    /** Extra modifiers which are common to all program elements. */
+    public Modifiers getModifiers(Attributes attributes) {
+        Modifiers modifiers = new Modifiers();
+        modifiers.isStatic = false;
+        if (attributes.getValue("static").compareTo("true") == 0)
+            modifiers.isStatic = true;
+        modifiers.isFinal = false;
+        if (attributes.getValue("final").compareTo("true") == 0)
+            modifiers.isFinal = true;
+        modifiers.isDeprecated = false;
+        String cdt = attributes.getValue("deprecated");
+        if (cdt.compareTo("not deprecated") == 0) {
+            modifiers.isDeprecated = false;
+            currentDepText = null;
+        } else if (cdt.compareTo("deprecated, no comment") == 0) {
+            modifiers.isDeprecated = true;
+            currentDepText = null;
+        } else {
+            modifiers.isDeprecated = true;
+            currentDepText = API.showHTMLTags(cdt);
+        }
+        modifiers.visibility = attributes.getValue("visibility");
+        return modifiers;
+    }
+
+    public void warning(SAXParseException e) {
+        System.out.println("Warning (" + e.getLineNumber() + "): parsing XML API file:" + e);
+        e.printStackTrace();
+    }
+
+    public void error(SAXParseException e) {
+        System.out.println("Error (" + e.getLineNumber() + "): parsing XML API file:" + e);
+        e.printStackTrace();
+        System.exit(1);
+    }
+    
+    public void fatalError(SAXParseException e) {
+        System.out.println("Fatal Error (" + e.getLineNumber() + "): parsing XML API file:" + e);
+        e.printStackTrace();
+        System.exit(1);
+    }    
+
+    /** 
+     * If set, then attempt to convert @link tags to HTML links. 
+     * A few of the HTML links may be broken links.
+     */
+    private static boolean convertAtLinks = true;
+
+    /** Set to enable increased logging verbosity for debugging. */
+    private static boolean trace = false;
+
+}
diff --git a/src/jdiff/ClassAPI.java b/src/jdiff/ClassAPI.java
new file mode 100755
index 0000000..9490cc7
--- /dev/null
+++ b/src/jdiff/ClassAPI.java
@@ -0,0 +1,91 @@
+package jdiff;
+
+import java.io.*;
+import java.util.*;
+
+/** 
+ * Class to represent a class, analogous to ClassDoc in the 
+ * Javadoc doclet API. 
+ * 
+ * The method used for Collection comparison (compareTo) must make its
+ * comparison based upon everything that is known about this class.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+class ClassAPI implements Comparable {
+
+    /** Name of the class, not fully qualified. */
+    public String name_;
+
+    /** Set if this class is an interface. */
+    public boolean isInterface_;
+
+    /** Set if this class is abstract. */
+    boolean isAbstract_ = false;
+
+    /** Modifiers for this class. */
+    public Modifiers modifiers_;
+
+    /** Name of the parent class, or null if there is no parent. */
+    public String extends_; // Can only extend zero or one class or interface
+
+    /** Interfaces implemented by this class. */
+    public List implements_; // String[]
+
+    /** Constructors in this class. */
+    public List ctors_; // ConstructorAPI[]
+
+    /** Methods in this class. */
+    public List methods_; // MethodAPI[]
+
+    /** Fields in this class. */
+    public List fields_; //FieldAPI[]
+
+    /** The doc block, default is null. */
+    public String doc_ = null;
+
+    /** Constructor. */
+    public ClassAPI(String name, String parent, boolean isInterface, 
+                    boolean isAbstract, Modifiers modifiers) {
+        name_ = name;
+        extends_ = parent;
+        isInterface_ = isInterface;
+        isAbstract_ = isAbstract;
+        modifiers_ = modifiers;
+
+        implements_ = new ArrayList(); // String[]
+        ctors_ = new ArrayList(); // ConstructorAPI[]
+        methods_ = new ArrayList(); // MethodAPI[]
+        fields_ = new ArrayList(); // FieldAPI[]
+    }
+
+    /** Compare two ClassAPI objects by all the known information. */
+    public int compareTo(Object o) {
+        ClassAPI oClassAPI = (ClassAPI)o;
+        int comp = name_.compareTo(oClassAPI.name_);
+        if (comp != 0)
+            return comp;
+        if (isInterface_ != oClassAPI.isInterface_)
+            return -1;
+        if (isAbstract_ != oClassAPI.isAbstract_)
+            return -1;
+        comp = modifiers_.compareTo(oClassAPI.modifiers_);
+        if (comp != 0)
+            return comp;
+        if (APIComparator.docChanged(doc_, oClassAPI.doc_))
+            return -1;
+        return 0;
+    }  
+
+    /** 
+     * Tests two methods for equality using just the class name, 
+     * used by indexOf(). 
+     */
+    public boolean equals(Object o) {
+        if (name_.compareTo(((ClassAPI)o).name_) == 0)
+            return true;
+        return false;
+    }
+    
+}
diff --git a/src/jdiff/ClassDiff.java b/src/jdiff/ClassDiff.java
new file mode 100755
index 0000000..8742ab1
--- /dev/null
+++ b/src/jdiff/ClassDiff.java
@@ -0,0 +1,154 @@
+package jdiff;
+
+import java.util.*;
+import com.sun.javadoc.*;
+
+/**
+ * The changes between two classes.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+class ClassDiff {
+
+    /** Name of the class. */
+    public String name_;
+
+    /** Set if this class is an interface in the new API. */
+    public boolean isInterface_;
+
+    /** 
+     * A string describing the changes in inheritance. 
+     */
+    public String inheritanceChange_ = null;
+
+    /** 
+     * A string describing the changes in documentation. 
+     */
+    public String documentationChange_ = null;
+
+    /** 
+     * A string describing the changes in modifiers. 
+     * Changes can be in whether this is a class or interface, whether it is
+     * abstract, static, final, and in its visibility.
+     */
+    public String modifiersChange_ = null;
+
+    /** Constructors added in the new API. */
+    public List ctorsAdded = null;
+    /** Constructors removed in the new API. */
+    public List ctorsRemoved = null;
+    /** Constructors changed in the new API. */
+    public List ctorsChanged = null;
+
+    /** Methods added in the new API. */
+    public List methodsAdded = null;
+    /** Methods removed in the new API. */
+    public List methodsRemoved = null;
+    /** Methods changed in the new API. */
+    public List methodsChanged = null;
+
+    /** Fields added in the new API. */
+    public List fieldsAdded = null;
+    /** Fields removed in the new API. */
+    public List fieldsRemoved = null;
+    /** Fields changed in the new API. */
+    public List fieldsChanged = null;
+
+    /* The percentage difference for this class. */
+    public double pdiff = 0.0;
+
+    /** Default constructor. */
+    public ClassDiff(String name) {
+        name_ = name;
+        isInterface_ = false;
+
+        ctorsAdded = new ArrayList(); // ConstructorAPI[]
+        ctorsRemoved = new ArrayList(); // ConstructorAPI[]
+        ctorsChanged = new ArrayList(); // MemberDiff[]
+
+        methodsAdded = new ArrayList(); // MethodAPI[]
+        methodsRemoved = new ArrayList(); // MethodAPI[]
+        methodsChanged = new ArrayList(); // MemberDiff[]
+
+        fieldsAdded = new ArrayList(); // FieldAPI[]
+        fieldsRemoved = new ArrayList(); // FieldAPI[]
+        fieldsChanged = new ArrayList(); // MemberDiff[]
+    }   
+
+    /** 
+     * Compare the inheritance details of two classes and produce 
+     * a String for the inheritanceChanges_ field in this class.
+     * If there is no difference, null is returned.
+     */
+    public static String diff(ClassAPI oldClass, ClassAPI newClass) {
+        Collections.sort(oldClass.implements_);
+        Collections.sort(newClass.implements_);
+        String res = "";
+        boolean hasContent = false;
+        if (oldClass.extends_ != null && newClass.extends_ != null &&
+            oldClass.extends_.compareTo(newClass.extends_) != 0) {
+            res += "The superclass changed from <code>" + oldClass.extends_ + "</code> to <code>" + newClass.extends_ + "</code>.<br>";
+            hasContent = true;
+        }
+        // Check for implemented interfaces which were removed
+        String removedInterfaces = "";
+        int numRemoved = 0;
+        Iterator iter = oldClass.implements_.iterator();
+        while (iter.hasNext()) {
+            String oldInterface = (String)(iter.next());
+            int idx = Collections.binarySearch(newClass.implements_, oldInterface);
+            if (idx < 0) {
+                if (numRemoved != 0)
+                    removedInterfaces += ", ";
+                removedInterfaces += oldInterface;
+                numRemoved++;
+            }
+        }
+        String addedInterfaces = "";
+        int numAdded = 0;
+        iter = newClass.implements_.iterator();
+        while (iter.hasNext()) {
+            String newInterface = (String)(iter.next());
+            int idx = Collections.binarySearch(oldClass.implements_, newInterface);
+            if (idx < 0) {
+                if (numAdded != 0)
+                    addedInterfaces += ", ";
+                addedInterfaces += newInterface;
+                numAdded++;
+            }
+        }
+        if (numRemoved != 0) {
+            if (hasContent)
+                res += " ";
+            if (numRemoved == 1)
+                res += "Removed interface <code>" + removedInterfaces + "</code>.<br>";
+            else
+                res += "Removed interfaces <code>" + removedInterfaces + "</code>.<br>";
+            hasContent = true;
+        }
+        if (numAdded != 0) {
+            if (hasContent)
+                res += " ";
+            if (numAdded == 1)
+                res += "Added interface <code>" + addedInterfaces + "</code>.<br>";
+            else
+                res += "Added interfaces <code>" + addedInterfaces + "</code>.<br>";
+            hasContent = true;
+        }
+        if (res.compareTo("") == 0)
+            return null;
+        return res;
+    }
+
+    /** Add a change in the modifiers. */
+    public void addModifiersChange(String commonModifierChanges) {
+        if (commonModifierChanges != null) {
+            if (modifiersChange_ == null)
+                modifiersChange_ = commonModifierChanges;
+            else
+                modifiersChange_ += " " + commonModifierChanges;
+        }
+    }
+}
+
diff --git a/src/jdiff/Comments.java b/src/jdiff/Comments.java
new file mode 100755
index 0000000..066e4f0
--- /dev/null
+++ b/src/jdiff/Comments.java
@@ -0,0 +1,551 @@
+package jdiff;
+
+import java.io.*;
+import java.util.*;
+
+/* For SAX XML parsing */
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.InputSource;
+import org.xml.sax.helpers.*;
+
+/**
+ * Creates a Comments from an XML file. The Comments object is the internal 
+ * representation of the comments for the changes.
+ * All methods in this class for populating a Comments object are static.
+ * 
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+public class Comments {
+
+    /** 
+     * All the possible comments known about, accessible by the commentID.
+     */
+    public static Hashtable allPossibleComments = new Hashtable();
+
+    /** The old Comments object which is populated from the file read in. */ 
+    private static Comments oldComments_ = null;
+
+    /** Default constructor. */
+    public Comments() {
+        commentsList_ = new ArrayList(); // SingleComment[]
+    }   
+  
+    // The list of comments elements associated with this objects
+    public List commentsList_ = null; // SingleComment[]
+
+    /** 
+     * Read the file where the XML for comments about the changes between
+     * the old API and new API is stored and create a Comments object for 
+     * it. The Comments object may be null if no file exists.
+     */
+    public static Comments readFile(String filename) {
+        // If validation is desired, write out the appropriate comments.xsd 
+        // file in the same directory as the comments XML file.
+        if (XMLToAPI.validateXML) {
+            writeXSD(filename);
+        }
+
+        // If the file does not exist, return null
+        File f = new File(filename);
+        if (!f.exists())
+            return null;
+
+        // The instance of the Comments object which is populated from the file. 
+        oldComments_ = new Comments();
+        try {
+            DefaultHandler handler = new CommentsHandler(oldComments_);
+            XMLReader parser = null;
+            try {
+                String parserName = System.getProperty("org.xml.sax.driver");
+                if (parserName == null) {
+                    parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
+                } else {
+                    // Let the underlying mechanisms try to work out which 
+                    // class to instantiate
+                    parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader();
+                }
+            } catch (SAXException saxe) {
+                System.out.println("SAXException: " + saxe);
+                saxe.printStackTrace();
+                System.exit(1);
+            }
+
+            if (XMLToAPI.validateXML) {
+                parser.setFeature("http://xml.org/sax/features/namespaces", true);
+                parser.setFeature("http://xml.org/sax/features/validation", true);
+                parser.setFeature("http://apache.org/xml/features/validation/schema", true);
+            }
+            parser.setContentHandler(handler);
+            parser.setErrorHandler(handler);
+            parser.parse(new InputSource(new FileInputStream(new File(filename))));
+        } catch(org.xml.sax.SAXNotRecognizedException snre) {
+            System.out.println("SAX Parser does not recognize feature: " + snre);
+            snre.printStackTrace();
+            System.exit(1);
+        } catch(org.xml.sax.SAXNotSupportedException snse) {
+            System.out.println("SAX Parser feature is not supported: " + snse);
+            snse.printStackTrace();
+            System.exit(1);
+        } catch(org.xml.sax.SAXException saxe) {
+            System.out.println("SAX Exception parsing file '" + filename + "' : " + saxe);
+            saxe.printStackTrace();
+            System.exit(1);
+        } catch(java.io.IOException ioe) {
+            System.out.println("IOException parsing file '" + filename + "' : " + ioe);
+            ioe.printStackTrace();
+            System.exit(1);
+        }
+
+        Collections.sort(oldComments_.commentsList_);
+        return oldComments_;
+    } //readFile()
+
+    /**
+     * Write the XML Schema file used for validation.
+     */
+    public static void writeXSD(String filename) {
+        String xsdFileName = filename;
+        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+1);
+        } else if (idx != -1  && idx2 == -1) {
+            xsdFileName = xsdFileName.substring(0, idx+1);
+        } else if (idx != -1  && idx2 != -1) {
+            int max = idx2 > idx ? idx2 : idx;
+            xsdFileName = xsdFileName.substring(0, max+1);
+        }
+        xsdFileName += "comments.xsd";
+        try {
+            FileOutputStream fos = new FileOutputStream(xsdFileName);
+            PrintWriter xsdFile = new PrintWriter(fos);
+            // The contents of the comments.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 comments.");
+            xsdFile.println("  </xsd:documentation>");
+            xsdFile.println("</xsd:annotation>");
+            xsdFile.println();
+            xsdFile.println("<xsd:element name=\"comments\" type=\"commentsType\"/>");
+            xsdFile.println();
+            xsdFile.println("<xsd:complexType name=\"commentsType\">");
+            xsdFile.println("  <xsd:sequence>");
+            xsdFile.println("    <xsd:element name=\"comment\" type=\"commentType\" minOccurs='0' 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=\"commentType\">");
+            xsdFile.println("  <xsd:sequence>");
+            xsdFile.println("    <xsd:element name=\"identifier\" type=\"identifierType\" minOccurs='1' maxOccurs='unbounded'/>");
+            xsdFile.println("    <xsd:element name=\"text\" type=\"xsd:string\" minOccurs='1' maxOccurs='1'/>");
+            xsdFile.println("  </xsd:sequence>");
+            xsdFile.println("</xsd:complexType>");
+            xsdFile.println();
+            xsdFile.println("<xsd:complexType name=\"identifierType\">");
+            xsdFile.println("  <xsd:attribute name=\"id\" 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);
+        }
+    }
+
+//
+// Methods to add data to a Comments object. Called by the XML parser and the 
+// report generator.
+//
+
+    /**
+     * Add the SingleComment object to the list of comments kept by this 
+     * object. 
+     */
+    public void addComment(SingleComment comment) {
+        commentsList_.add(comment); 
+    }
+
+//
+// Methods to get data from a Comments object. Called by the report generator
+//
+
+    /** 
+     * The text placed into XML comments file where there is no comment yet.
+     * It never appears in reports.
+     */
+    public static final String placeHolderText = "InsertCommentsHere";
+    
+    /** 
+     * Return the comment associated with the given id in the Comment object.
+     * If there is no such comment, return the placeHolderText.
+     */
+    public static String getComment(Comments comments, String id) {
+        if (comments == null)
+            return placeHolderText;
+        SingleComment key = new SingleComment(id, null);
+        int idx = Collections.binarySearch(comments.commentsList_, key);
+        if (idx < 0) {
+            return placeHolderText;
+        } else {
+            int startIdx = comments.commentsList_.indexOf(key);
+            int endIdx = comments.commentsList_.indexOf(key);
+            int numIdx = endIdx - startIdx + 1;
+            if (numIdx != 1) {
+                System.out.println("Warning: " + numIdx + " identical ids in the existing comments file. Using the first instance.");
+            }
+            SingleComment singleComment = (SingleComment)(comments.commentsList_.get(idx));
+            // Convert @link tags to links
+            return singleComment.text_;
+        }
+    }
+
+    /** 
+     * Convert @link tags to HTML links. 
+     */
+    public static String convertAtLinks(String text, String currentElement, 
+                                        PackageAPI pkg, ClassAPI cls) {
+        if (text == null)
+            return null;
+	
+        StringBuffer result = new StringBuffer();
+        
+        int state = -1;
+        
+        final int NORMAL_TEXT = -1;
+        final int IN_LINK = 1;
+        final int IN_LINK_IDENTIFIER = 2;
+        final int IN_LINK_IDENTIFIER_REFERENCE = 3;
+        final int IN_LINK_IDENTIFIER_REFERENCE_PARAMS = 6;
+        final int IN_LINK_LINKTEXT = 4;
+        final int END_OF_LINK = 5;
+
+        StringBuffer identifier = null;
+        StringBuffer identifierReference = null;
+        StringBuffer linkText = null;
+        
+        // Figure out relative reference if required.
+        String ref = "";
+        if (currentElement.compareTo("class") == 0 ||
+            currentElement.compareTo("interface") == 0) {
+	    ref = pkg.name_ + "." + cls.name_ + ".";
+        } else if (currentElement.compareTo("package") == 0) {
+	    ref = pkg.name_ + ".";
+        }
+        ref = ref.replace('.', '/');        
+        
+        for (int i=0; i < text.length(); i++) {
+	    char c = text.charAt( i);
+	    char nextChar = i < text.length()-1 ? text.charAt( i+1) : (char)-1;
+	    int remainingChars = text.length() - i;
+          
+	    switch (state) {
+	    case NORMAL_TEXT:
+		if (c == '{' && remainingChars >= 5) {
+		    if ("{@link".equals(text.substring(i, i + 6))) {
+			state = IN_LINK;
+			identifier = null;
+			identifierReference = null;
+			linkText = null;
+			i += 5;
+			continue;
+		    }
+		}
+		result.append( c);
+		break;
+	    case IN_LINK:
+		if (Character.isWhitespace(nextChar)) continue;
+		if (nextChar == '}') {
+		    // End of the link
+		    state = END_OF_LINK;
+		} else if (!Character.isWhitespace(nextChar)) {
+		    state = IN_LINK_IDENTIFIER;
+		}
+		break;
+            case IN_LINK_IDENTIFIER:
+		if (identifier == null) {
+		    identifier = new StringBuffer();
+		}
+            
+		if (c == '#') {
+		    // We have a reference.
+		    state = IN_LINK_IDENTIFIER_REFERENCE;
+		    // Don't append #
+		    continue;
+		} else if (Character.isWhitespace(c)) {
+		    // We hit some whitespace: the next character is the beginning
+		    // of the link text.
+		    state = IN_LINK_LINKTEXT;
+		    continue;
+		}
+		identifier.append(c);              
+		// Check for a } that ends the link.
+		if (nextChar == '}') {
+		    state = END_OF_LINK;
+		}
+		break;
+            case IN_LINK_IDENTIFIER_REFERENCE:
+		if (identifierReference == null) {
+		    identifierReference = new StringBuffer();
+		}
+		if (Character.isWhitespace(c)) {
+		    state = IN_LINK_LINKTEXT;
+		    continue;
+		}
+		identifierReference.append(c);
+              
+		if (c == '(') {
+		    state = IN_LINK_IDENTIFIER_REFERENCE_PARAMS;
+		}
+              
+		if (nextChar == '}') {
+		    state = END_OF_LINK;
+		}
+		break;
+            case IN_LINK_IDENTIFIER_REFERENCE_PARAMS:
+		// We're inside the parameters of a reference. Spaces are allowed.
+		if (c == ')') {
+		    state = IN_LINK_IDENTIFIER_REFERENCE;
+		}
+		identifierReference.append(c);
+		if (nextChar == '}') {
+		    state = END_OF_LINK;
+		}
+		break;
+            case IN_LINK_LINKTEXT:
+		if (linkText == null) linkText = new StringBuffer();
+              
+		linkText.append(c);
+              
+		if (nextChar == '}') {
+		    state = END_OF_LINK;
+		}
+		break;
+            case END_OF_LINK:
+		if (identifier != null) {
+		    result.append("<A HREF=\"");
+		    result.append(HTMLReportGenerator.newDocPrefix);
+		    result.append(ref);
+		    result.append(identifier.toString().replace('.', '/'));
+		    result.append(".html");
+		    if (identifierReference != null) {
+			result.append("#");
+			result.append(identifierReference);
+		    }
+		    result.append("\">");   // target=_top?
+                
+		    result.append("<TT>");
+		    if (linkText != null) {
+			result.append(linkText);
+		    } else {
+			result.append(identifier);
+			if (identifierReference != null) {
+			    result.append(".");
+			    result.append(identifierReference);
+			}
+		    }
+		    result.append("</TT>");
+		    result.append("</A>");
+		}
+		state = NORMAL_TEXT;
+		break;
+	    }
+        }
+        return result.toString();
+    }
+
+//
+// Methods to write a Comments object out to a file.
+//
+
+    /**
+     * Write the XML representation of comments to a file.
+     *
+     * @param outputFileName The name of the comments file.
+     * @param oldComments The old comments on the changed APIs.
+     * @param newComments The new comments on the changed APIs.
+     * @return true if no problems encountered
+     */
+    public static boolean writeFile(String outputFileName, 
+                                    Comments newComments) {
+        try {
+            FileOutputStream fos = new FileOutputStream(outputFileName);
+            outputFile = new PrintWriter(fos);
+            newComments.emitXMLHeader(outputFileName);
+            newComments.emitComments();
+            newComments.emitXMLFooter();
+            outputFile.close();
+        } catch(IOException e) {
+            System.out.println("IO Error while attempting to create " + outputFileName);
+            System.out.println("Error: "+ e.getMessage());
+            System.exit(1);
+        }
+        return true;
+    }
+    
+    /**
+     * Write the Comments object out in XML.
+     */
+    public void emitComments() {
+        Iterator iter = commentsList_.iterator();
+        while (iter.hasNext()) {
+            SingleComment currComment = (SingleComment)(iter.next());
+            if (!currComment.isUsed_)
+                outputFile.println("<!-- This comment is no longer used ");
+            outputFile.println("<comment>");
+            outputFile.println("  <identifier id=\"" + currComment.id_ + "\"/>");
+            outputFile.println("  <text>");
+            outputFile.println("    " + currComment.text_);
+            outputFile.println("  </text>");
+            outputFile.println("</comment>");
+            if (!currComment.isUsed_)
+                outputFile.println("-->");
+        }        
+    }
+
+    /** 
+     * Dump the contents of a Comments object out for inspection.
+     */
+    public void dump() {
+        Iterator iter = commentsList_.iterator();
+        int i = 0;
+        while (iter.hasNext()) {
+            i++;
+            SingleComment currComment = (SingleComment)(iter.next());
+            System.out.println("Comment " + i);
+            System.out.println("id = " + currComment.id_);
+            System.out.println("text = \"" + currComment.text_ + "\"");
+            System.out.println("isUsed = " + currComment.isUsed_);
+        }        
+    }
+
+    /**
+     * Emit messages about which comments are now unused and which are new.
+     */
+    public static void noteDifferences(Comments oldComments, Comments newComments) {
+        if (oldComments == null) {
+            System.out.println("Note: all the comments have been newly generated");
+            return;
+        }
+        
+        // See which comment ids are no longer used and add those entries to 
+        // the new comments, marking them as unused.
+        Iterator iter = oldComments.commentsList_.iterator();
+        while (iter.hasNext()) {
+            SingleComment oldComment = (SingleComment)(iter.next());
+            int idx = Collections.binarySearch(newComments.commentsList_, oldComment);
+            if (idx < 0) {
+                System.out.println("Warning: comment \"" + oldComment.id_ + "\" is no longer used.");
+                oldComment.isUsed_ = false;
+                newComments.commentsList_.add(oldComment);
+            }
+        }        
+        
+    }
+
+    /**
+     * Emit the XML header.
+     */
+    public void emitXMLHeader(String filename) {
+        outputFile.println("<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"no\"?>");
+        outputFile.println("<comments");
+        outputFile.println("  xmlns:xsi='" + RootDocToXML.baseURI + "/2001/XMLSchema-instance'");
+        outputFile.println("  xsi:noNamespaceSchemaLocation='comments.xsd'");
+        // Extract the identifier from the filename by removing the suffix
+        int idx = filename.lastIndexOf('.');
+        String apiIdentifier = filename.substring(0, idx);
+        // Also remove the output directory and directory separator if present
+        if (HTMLReportGenerator.commentsDir != null)
+	    apiIdentifier = apiIdentifier.substring(HTMLReportGenerator.commentsDir.length()+1);
+        else if (HTMLReportGenerator.outputDir != null)
+            apiIdentifier = apiIdentifier.substring(HTMLReportGenerator.outputDir.length()+1);
+        // Also remove "user_comments_for_"
+        apiIdentifier = apiIdentifier.substring(18);
+        outputFile.println("  name=\"" + apiIdentifier + "\"");
+        outputFile.println("  jdversion=\"" + JDiff.version + "\">");
+        outputFile.println();
+        outputFile.println("<!-- Use this file to enter an API change description. For example, when you remove a class, ");
+        outputFile.println("     you can enter a comment for that class that points developers to the replacement class. ");
+        outputFile.println("     You can also provide a change summary for modified API, to give an overview of the changes ");
+        outputFile.println("     why they were made, workarounds, etc.  -->");
+        outputFile.println();
+        outputFile.println("<!-- When the API diffs report is generated, the comments in this file get added to the tables of ");
+        outputFile.println("     removed, added, and modified packages, classes, methods, and fields. This file does not ship ");
+        outputFile.println("     with the final report. -->");
+        outputFile.println();
+        outputFile.println("<!-- The id attribute in an identifier element identifies the change as noted in the report. ");
+        outputFile.println("     An id has the form package[.class[.[ctor|method|field].signature]], where [] indicates optional ");
+        outputFile.println("     text. A comment element can have multiple identifier elements, which will will cause the same ");
+        outputFile.println("     text to appear at each place in the report, but will be converted to separate comments when the ");
+        outputFile.println("     comments file is used. -->");
+        outputFile.println();
+        outputFile.println("<!-- HTML tags in the text field will appear in the report. You also need to close p HTML elements, ");
+        outputFile.println("     used for paragraphs - see the top-level documentation. -->");
+        outputFile.println();
+        outputFile.println("<!-- You can include standard javadoc links in your change descriptions. You can use the @first command  ");
+        outputFile.println("     to cause jdiff to include the first line of the API documentation. You also need to close p HTML ");
+        outputFile.println("     elements, used for paragraphs - see the top-level documentation. -->");
+        outputFile.println();
+    }
+
+    /**
+     * Emit the XML footer.
+     */
+    public void emitXMLFooter() {
+        outputFile.println();
+        outputFile.println("</comments>");
+    }
+
+    private static List oldAPIList = null;
+    private static List newAPIList = null;
+
+    /** 
+     * Return true if the given HTML tag has no separate </tag> end element. 
+     *
+     * If you want to be able to use sloppy HTML in your comments, then you can
+     * add the element, e.g. li back into the condition here. However, if you 
+     * then become more careful and do provide the closing tag, the output is 
+     * generally just the closing tag, which is incorrect.
+     *
+     * tag.equalsIgnoreCase("tr") || // Is sometimes minimized
+     * tag.equalsIgnoreCase("th") || // Is sometimes minimized
+     * tag.equalsIgnoreCase("td") || // Is sometimes minimized
+     * tag.equalsIgnoreCase("dt") || // Is sometimes minimized
+     * tag.equalsIgnoreCase("dd") || // Is sometimes minimized
+     * tag.equalsIgnoreCase("img") || // Is sometimes minimized
+     * tag.equalsIgnoreCase("code") || // Is sometimes minimized (error)
+     * tag.equalsIgnoreCase("font") || // Is sometimes minimized (error)
+     * tag.equalsIgnoreCase("ul") || // Is sometimes minimized
+     * tag.equalsIgnoreCase("ol") || // Is sometimes minimized
+     * tag.equalsIgnoreCase("li") // Is sometimes minimized
+     */
+    public static boolean isMinimizedTag(String tag) {
+        if (tag.equalsIgnoreCase("p") ||
+            tag.equalsIgnoreCase("br") ||
+            tag.equalsIgnoreCase("hr")
+            ) {
+            return true;
+	}
+        return false;
+    }
+
+    /** 
+     * The file where the XML representing the new Comments object is stored. 
+     */
+    private static PrintWriter outputFile = null;
+    
+}
+
+
diff --git a/src/jdiff/CommentsHandler.java b/src/jdiff/CommentsHandler.java
new file mode 100755
index 0000000..8061fbe
--- /dev/null
+++ b/src/jdiff/CommentsHandler.java
@@ -0,0 +1,210 @@
+package jdiff;
+
+import java.io.*;
+import java.util.*;
+
+/* For SAX XML parsing */
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Handle the parsing of an XML file and the generation of a Comments object.
+ *
+ * All HTML written for the comments sections in the report must
+ * use tags such as &lt;p/&gt; rather than just &lt;p&gt;, since the XML
+ * parser used requires that or matching end elements.
+ *
+ * From http://www.w3.org/TR/2000/REC-xhtml1-20000126:
+ * "Empty elements must either have an end tag or the start tag must end with /&lt;". 
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+class CommentsHandler extends DefaultHandler {
+
+    /** The Comments object which is populated from the XML file. */
+    public Comments comments_ = null;
+
+    /** The current SingleComment object being populated. */
+    private List currSingleComment_ = null; // SingleComment[]
+
+    /** Set if in text. */
+    private boolean inText = false;
+
+    /** The current text which is being assembled from chunks. */
+    private String currentText = null;
+    
+    /** The stack of SingleComments still waiting for comment text. */
+    private LinkedList tagStack = null;
+
+    /** Default constructor. */
+    public CommentsHandler(Comments comments) {
+        comments_ = comments;
+        tagStack = new LinkedList();
+    }   
+
+    public void startDocument() {
+    }
+    
+    public void endDocument() {
+        if (trace)
+            comments_.dump();
+    }
+
+    public void startElement(java.lang.String uri, java.lang.String localName,
+                             java.lang.String qName, Attributes attributes) {
+	// The change to JAXP compliance produced this change.
+	if (localName.equals(""))
+	    localName = qName;
+        if (localName.compareTo("comments") == 0) {
+            String commentsName = attributes.getValue("name");
+            String version = attributes.getValue("jdversion"); // Not used yet
+            if (commentsName == null) {
+                System.out.println("Error: no identifier found in the comments XML file.");
+                System.exit(3);
+            }
+            // Check the given names against the names of the APIs
+            int idx1 = JDiff.oldFileName.lastIndexOf('.');
+            int idx2 = JDiff.newFileName.lastIndexOf('.');
+            String filename2 = JDiff.oldFileName.substring(0, idx1) + 
+                "_to_" + JDiff.newFileName.substring(0, idx2);
+            if (filename2.compareTo(commentsName) != 0) {
+                System.out.println("Warning: API identifier in the comments XML file (" + filename2 + ") differs from the name of the file.");
+            }
+        } else if (localName.compareTo("comment") == 0) {
+            currSingleComment_ = new ArrayList(); // SingleComment[];
+        } else if (localName.compareTo("identifier") == 0) {
+            // May have multiple identifiers for one comment's text
+            String id = attributes.getValue("id");
+            SingleComment newComment = new SingleComment(id, null);
+            // Store it here until we can add text to it
+            currSingleComment_.add(newComment);
+        } else if (localName.compareTo("text") == 0) {
+            inText = true;
+            currentText = null;
+        } else {
+            if (inText) {
+                // Start of an element, probably an HTML element
+                addStartTagToText(localName, attributes);
+            } else {
+                System.out.println("Error: unknown element type: " + localName);
+                System.exit(-1);
+            }
+        }
+    }
+    
+    public void endElement(java.lang.String uri, java.lang.String localName, 
+                           java.lang.String qName) {
+	if (localName.equals(""))
+	    localName = qName;
+        if (localName.compareTo("text") == 0) {
+            inText = false;
+            addTextToComments();
+        } else if (inText) {
+            addEndTagToText(localName);
+        }
+
+    }
+    
+    /** Deal with a chunk of text. The text may come in multiple chunks. */
+    public void characters(char[] ch, int start, int length) {
+        if (inText) {
+            String chunk = new String(ch, start, length);
+            if (currentText == null)
+                currentText = chunk;
+            else
+                currentText += chunk;
+        }
+    }
+
+    /** 
+     * Trim the current text, check it is a sentence and add it to all 
+     * the comments which are waiting for it. 
+     */
+    public void addTextToComments() {
+        // Eliminate any whitespace at each end of the text.
+        currentText = currentText.trim();
+        // Check that it is a sentence
+        if (!currentText.endsWith(".") &&
+            !currentText.endsWith("?") &&
+            !currentText.endsWith("!") && 
+            currentText.compareTo(Comments.placeHolderText) != 0) {
+            System.out.println("Warning: text of comment does not end in a period: " + currentText);
+        }
+        // Add this comment to all the SingleComments waiting for it
+        Iterator iter = currSingleComment_.iterator();
+        while (iter.hasNext()) {
+            SingleComment currComment = (SingleComment)(iter.next());
+            if (currComment.text_ == null)
+                currComment.text_ = currentText;
+            else
+                currComment.text_ += currentText;
+            comments_.addComment(currComment);
+        }
+    }
+
+    /** 
+     * Add the start tag to the current comment text. 
+     */
+    public void addStartTagToText(String localName, Attributes attributes) {
+        // Need to insert the HTML tag into the current text
+        String currentHTMLTag = localName;
+        // Save the tag in a stack
+        tagStack.add(currentHTMLTag);
+        String tag = "<" + currentHTMLTag;
+        // Now add all the attributes into the current text
+        int len = attributes.getLength();
+        for (int i = 0; i < len; i++) {
+            String name = attributes.getLocalName(i);
+            String value = attributes.getValue(i);
+            tag += " " + name + "=\"" + value+ "\"";
+        }
+
+        // End the tag
+        if (Comments.isMinimizedTag(currentHTMLTag)) {
+            tag += "/>";
+        } else {
+            tag += ">";
+        }
+        // Now insert the HTML tag into the current text
+        if (currentText == null)
+            currentText = tag;
+        else
+            currentText += tag;
+    }
+
+    /** 
+     * Add the end tag to the current comment text. 
+     */
+    public void addEndTagToText(String localName) {
+        // Close the current HTML tag
+        String currentHTMLTag = (String)(tagStack.removeLast());
+        if (!Comments.isMinimizedTag(currentHTMLTag))
+            currentText += "</" + currentHTMLTag + ">";
+    }
+
+    public void warning(SAXParseException e) {
+        System.out.println("Warning (" + e.getLineNumber() + "): parsing XML comments file:" + e);
+        e.printStackTrace();
+    }
+
+    public void error(SAXParseException e) {
+        System.out.println("Error (" + e.getLineNumber() + "): parsing XML comments file:" + e);
+        e.printStackTrace();
+        System.exit(1);
+    }
+    
+    public void fatalError(SAXParseException e) {
+        System.out.println("Fatal Error (" + e.getLineNumber() + "): parsing XML comments file:" + e);
+        e.printStackTrace();
+        System.exit(1);
+    }    
+
+    /** Set to enable increased logging verbosity for debugging. */
+    private static final boolean trace = false;
+
+}
+
diff --git a/src/jdiff/CompareClassPdiffs.java b/src/jdiff/CompareClassPdiffs.java
new file mode 100755
index 0000000..bd0bf95
--- /dev/null
+++ b/src/jdiff/CompareClassPdiffs.java
@@ -0,0 +1,25 @@
+package jdiff;
+
+import java.util.*;
+
+/** 
+ * Class to compare two ClassDiff objects.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+class CompareClassPdiffs implements Comparator {
+    /** 
+     * Compare two class diffs by their percentage difference,
+     * and then by name.
+     */
+    public int compare(Object obj1, Object obj2){
+        ClassDiff c1 = (ClassDiff)obj1;
+        ClassDiff c2 = (ClassDiff)obj2;
+        if (c1.pdiff < c2.pdiff)
+            return 1;
+        if (c1.pdiff > c2.pdiff)
+            return -1;
+        return c1.name_.compareTo(c2.name_);
+    }
+}
diff --git a/src/jdiff/ComparePkgPdiffs.java b/src/jdiff/ComparePkgPdiffs.java
new file mode 100755
index 0000000..187e7bf
--- /dev/null
+++ b/src/jdiff/ComparePkgPdiffs.java
@@ -0,0 +1,25 @@
+package jdiff;
+
+import java.util.*;
+
+/** 
+ * Class to compare two PackageDiff objects.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+class ComparePkgPdiffs implements Comparator {
+    /** 
+     * Compare two package diffs by their percentage difference,
+     * and then by name.
+     */
+    public int compare(Object obj1, Object obj2){
+        PackageDiff p1 = (PackageDiff)obj1;
+        PackageDiff p2 = (PackageDiff)obj2;
+        if (p1.pdiff < p2.pdiff)
+            return 1;
+        if (p1.pdiff > p2.pdiff)
+            return -1;
+        return p1.name_.compareTo(p2.name_);
+    }
+}
diff --git a/src/jdiff/ConstructorAPI.java b/src/jdiff/ConstructorAPI.java
new file mode 100755
index 0000000..7390a4d
--- /dev/null
+++ b/src/jdiff/ConstructorAPI.java
@@ -0,0 +1,66 @@
+package jdiff;
+
+import java.io.*;
+import java.util.*;
+
+/** 
+ * Class to represent a constructor, analogous to ConstructorDoc in the 
+ * Javadoc doclet API. 
+ *
+ * The method used for Collection comparison (compareTo) must make its
+ * comparison based upon everything that is known about this constructor.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+class ConstructorAPI implements Comparable {
+    /** 
+     * The type of the constructor, being all the parameter types
+     * separated by commas.
+     */
+    public String type_ = null;
+    
+    /** 
+     * The exceptions thrown by this constructor, being all the exception types
+     * separated by commas. "no exceptions" if no exceptions are thrown.
+     */
+    public String exceptions_ = "no exceptions";
+    
+    /** Modifiers for this class. */
+    public Modifiers modifiers_;
+
+    /** The doc block, default is null. */
+    public String doc_ = null;
+
+    /** Constructor. */
+    public ConstructorAPI(String type, Modifiers modifiers) {
+        type_ = type;
+        modifiers_ = modifiers;
+    }
+
+    /** Compare two ConstructorAPI objects by type and modifiers. */
+    public int compareTo(Object o) {
+        ConstructorAPI constructorAPI = (ConstructorAPI)o;
+        int comp = type_.compareTo(constructorAPI.type_);
+        if (comp != 0)
+            return comp;
+        comp = exceptions_.compareTo(constructorAPI.exceptions_);
+        if (comp != 0)
+            return comp;
+        comp = modifiers_.compareTo(constructorAPI.modifiers_);
+        if (comp != 0)
+            return comp;
+        if (APIComparator.docChanged(doc_, constructorAPI.doc_))
+            return -1;
+        return 0;
+    }
+
+    /** 
+     * Tests two constructors, using just the type, used by indexOf(). 
+     */
+    public boolean equals(Object o) {
+        if (type_.compareTo(((ConstructorAPI)o).type_) == 0)
+            return true;
+        return false;
+    }
+}  
diff --git a/src/jdiff/Diff.java b/src/jdiff/Diff.java
new file mode 100755
index 0000000..a9c9776
--- /dev/null
+++ b/src/jdiff/Diff.java
@@ -0,0 +1,654 @@
+package jdiff;
+
+import java.io.*;
+import java.util.*;
+
+/** 
+ * Class to generate colored differences between two sections of HTML text.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+class Diff {
+
+    /** 
+     * Save the differences between the two strings in a DiffOutput object
+     * for later use.
+     * 
+     * @param id A per-package unique identifier for each documentation 
+     *           change.
+     */ 
+    static String saveDocDiffs(String pkgName, String className, 
+                               String oldDoc, String newDoc, 
+                               String id, String title) {
+        // Generate the string which will link to this set of diffs
+        if (noDocDiffs)
+            return "Documentation changed from ";
+        if (oldDoc == null || newDoc == null) {
+            return "Documentation changed from ";
+        }
+
+        // Generate the differences. 
+        generateDiffs(pkgName, className, oldDoc, newDoc, id, title);
+
+        return "Documentation <a href=\"" + diffFileName + pkgName +
+            HTMLReportGenerator.reportFileExt + "#" + id + 
+            "\">changed</a> from ";
+    }
+    
+    /** 
+     * Generate the differences. 
+     */
+    static void generateDiffs(String pkgName, String className,
+                              String oldDoc, String newDoc, 
+                              String id, String title) {
+        String[] oldDocWords = parseDoc(oldDoc);
+        String[] newDocWords = parseDoc(newDoc);
+
+        DiffMyers diff = new DiffMyers(oldDocWords, newDocWords);
+        DiffMyers.change script = diff.diff_2(false);
+        script = mergeDiffs(oldDocWords, newDocWords, script);
+        String text = "<A NAME=\"" + id + "\"></A>" + title + "<br><br>";
+        // Generate the differences in blockquotes to cope with unterminated 
+        // HTML tags
+        text += "<blockquote>";
+        text = addDiffs(oldDocWords, newDocWords, script, text);
+        text += "</blockquote>";
+        docDiffs.add(new DiffOutput(pkgName, className, id, title, text));
+    }
+
+    /** 
+     * Convert the string to an array of strings, but don't break HTML tags up.
+     */
+    static String[] parseDoc(String doc) {
+        String delimiters = " .,;:?!(){}[]\"'~@#$%^&*+=_-|\\<>/";
+        StringTokenizer st = new StringTokenizer(doc, delimiters, true);
+        List docList = new ArrayList();
+        boolean inTag = false;
+        String tag = null;
+        while (st.hasMoreTokens()) {
+            String tok = st.nextToken();
+            if (!inTag) {
+                if (tok.compareTo("<") == 0) {
+                    tag = tok;
+                    if (st.hasMoreTokens()) {
+                        // See if this really is a tag
+                        tok = st.nextToken();
+                        char ch = tok.charAt(0);
+                        if (Character.isLetter(ch) || ch == '/') {
+                            inTag = true;
+                            tag += tok;
+                        }
+                    }
+                    if (!inTag)
+                      docList.add(tag);
+                } else { 
+                    docList.add(tok);
+                }
+            } else {
+                // Add all tokens to the tag until the closing > is seen
+                if (tok.compareTo(">") == 0) {
+                    inTag = false;
+                    tag += tok;
+                    docList.add(tag);
+                } else { 
+                    tag += tok;
+                }
+            }
+        }   
+        if (inTag) {
+            // An unterminated tag, or more likely, < used instead of &lt;
+            // There are no nested tags such as <a <b>> in HTML
+            docList.add(tag);
+        }
+        String[] docWords = new String[docList.size()];
+        docWords = (String[])docList.toArray(docWords);
+        return docWords;
+    }
+
+    /** 
+     * For improved readability, merge changes of the form 
+     *  "delete 1, insert 1, space, delete 1, insert 1"
+     * to 
+     *  "delete 3, insert 3" (including the space).
+     *
+     * @param oldDocWords The original documentation as a String array
+     * @param newDocWords The new documentation as a String array
+     */
+    static DiffMyers.change mergeDiffs(String[] oldDocWords, String[] newDocWords, 
+                                       DiffMyers.change script) {
+        if (script.link == null)
+            return script; // Only one change
+        DiffMyers.change hunk = script;
+        DiffMyers.change lasthunk = null; // Set to the last potential hunk
+        int startOld = 0;
+        for (; hunk != null; hunk = hunk.link) {
+            int deletes = hunk.deleted;
+            int inserts = hunk.inserted;
+            if (lasthunk == null) {
+                if (deletes == 1 && inserts == 1) {
+                    // This is the start of a potential merge
+                    lasthunk = hunk;
+                } 
+                continue;
+            } else {
+                int first0 = hunk.line0; // Index of first deleted word
+                int first1 = hunk.line1; // Index of first inserted word
+                if (deletes == 1 && inserts == 1 && 
+                    oldDocWords[first0 - 1].compareTo(" ") == 0 && 
+                    newDocWords[first1 - 1].compareTo(" ") == 0 &&
+                    first0 == lasthunk.line0 + lasthunk.deleted + 1 &&
+                    first1 == lasthunk.line1 + lasthunk.inserted + 1) {
+                    // Merge this change into the last change
+                    lasthunk.deleted += 2;
+                    lasthunk.inserted += 2;
+                    lasthunk.link = hunk.link;
+                } else {
+                    lasthunk = null;
+                }
+            }
+        }            
+        return script;
+    }
+
+    /** 
+     * Add the differences to the text passed in. The old documentation is 
+     * edited using the edit script provided by the DiffMyers object.
+     * Do not display diffs in HTML tags.
+     *
+     * @param oldDocWords The original documentation as a String array
+     * @param newDocWords The new documentation as a String array
+     * @return The text for this documentation difference
+     */
+    static String addDiffs(String[] oldDocWords, String[] newDocWords, 
+                           DiffMyers.change script, String text) {
+        String res = text;
+        DiffMyers.change hunk = script;
+        int startOld = 0;
+        if (trace) {
+            System.out.println("Old Text:");
+            for (int i = 0; i < oldDocWords.length; i++) {
+                System.out.print(oldDocWords[i]);
+            }
+            System.out.println(":END");
+            System.out.println("New Text:");
+            for (int i = 0; i < newDocWords.length; i++) {
+                System.out.print(newDocWords[i]);
+            }
+            System.out.println(":END");
+        }
+
+        for (; hunk != null; hunk = hunk.link) {
+            int deletes = hunk.deleted;
+            int inserts = hunk.inserted;
+            if (deletes == 0 && inserts == 0) {
+                continue; // Not clear how this would occur, but handle it
+            }
+
+            // Determine the range of word and delimiter numbers involved 
+            // in each file.
+            int first0 = hunk.line0; // Index of first deleted word
+            // Index of last deleted word, invalid if deletes == 0
+            int last0 = hunk.line0 + hunk.deleted - 1; 
+            int first1 = hunk.line1; // Index of first inserted word
+            // Index of last inserted word, invalid if inserts == 0
+            int last1 = hunk.line1 + hunk.inserted - 1;
+            
+            if (trace) {
+                System.out.println("HUNK: ");
+                System.out.println("inserts: " + inserts);
+                System.out.println("deletes: " + deletes);
+                System.out.println("first0: " + first0);
+                System.out.println("last0: " + last0);
+                System.out.println("first1: " + first1);
+                System.out.println("last1: " + last1);
+            }
+
+            // Emit the original document up to this change
+            for (int i = startOld; i < first0; i++) {
+                res += oldDocWords[i];
+            }
+            // Record where to start the next hunk from
+            startOld = last0 + 1;
+            // Emit the deleted words, but struck through
+            // but do not emit deleted HTML tags
+            if (deletes != 0) {
+                boolean inStrike = false;
+                for (int i = first0; i <= last0; i++) {
+                    if (!oldDocWords[i].startsWith("<") && 
+                        !oldDocWords[i].endsWith(">")) {
+                        if (!inStrike) {
+                            if (deleteEffect == 0)
+                                res += "<strike>";
+                            else if (deleteEffect == 1)
+                                res += "<span style=\"background: #FFCCCC\">";
+                            inStrike = true;
+                        }
+                        res += oldDocWords[i];
+                    }
+                }
+                if (inStrike) {
+                    if (deleteEffect == 0)
+                        res += "</strike>";
+                    else if (deleteEffect == 1)
+                        res += "</span>";
+                }
+            }
+            // Emit the inserted words, but do not emphasise new HTML tags
+            if (inserts != 0) {
+                boolean inEmph = false;
+                for (int i = first1; i <= last1; i++) {
+                    if (!newDocWords[i].startsWith("<") && 
+                        !newDocWords[i].endsWith(">")) {
+                        if (!inEmph) {
+                            if (insertEffect == 0)
+                                res += "<font color=\"red\">";
+                            else if (insertEffect == 1)
+                                res += "<span style=\"background: #FFFF00\">";
+                            inEmph = true;
+                        }
+                    }
+                    res += newDocWords[i];
+                }
+                if (inEmph) {
+                    if (insertEffect == 0)
+                        res += "</font>";
+                    else if (insertEffect == 1)
+                        res += "</span>";
+                }
+            }
+        } //for (; hunk != null; hunk = hunk.link)
+        // Print out the remaining part of the old text
+        for (int i = startOld; i < oldDocWords.length; i++) {
+            res += oldDocWords[i];
+        }
+        return res;
+    }
+
+    /** 
+     * Emit all the documentation differences into one file per package.
+     */ 
+    static void emitDocDiffs(String fullReportFileName) {
+        Collections.sort(docDiffs);
+
+        DiffOutput[] docDiffsArr = new DiffOutput[docDiffs.size()];
+        docDiffsArr = (DiffOutput[])docDiffs.toArray(docDiffsArr);
+
+        for (int i = 0; i < docDiffsArr.length; i++) {
+            DiffOutput diffOutput = docDiffsArr[i];
+            if (currPkgName == null || 
+                currPkgName.compareTo(diffOutput.pkgName_) != 0) {
+                // Open a different file for each package, add the HTML header,
+                // the navigation bar and some preamble.
+                if (currPkgName != null)
+                    closeDiffFile(); // Close the existing file
+                // Create the HTML link to the previous package
+                String prevPkgName = currPkgName;
+                if (currPkgName != null) {
+                    prevPkgName = diffFileName + docDiffsArr[i-1].pkgName_ +
+                    HTMLReportGenerator.reportFileExt;
+                }
+                // Set the current package name
+                currPkgName = diffOutput.pkgName_;
+                // Create the HTML link to the next package
+                String nextPkgName = null;
+                for (int j = i; j < docDiffsArr.length; j++) {
+                    if (currPkgName.compareTo(docDiffsArr[j].pkgName_) != 0) {
+                        nextPkgName = diffFileName + docDiffsArr[j].pkgName_ +
+                            HTMLReportGenerator.reportFileExt;
+                        break;
+                    }
+                }
+
+                String fullDiffFileName = fullReportFileName + 
+                    JDiff.DIR_SEP + diffFileName + currPkgName +
+                    HTMLReportGenerator.reportFileExt;
+                // Create the output file
+                try {
+                    FileOutputStream fos = new FileOutputStream(fullDiffFileName);
+                    diffFile = new PrintWriter(fos);
+                    
+                    // Write the HTML header
+                    diffFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Frameset//EN\"\"" + RootDocToXML.baseURI + "/TR/REC-html40/frameset.dtd\">");
+                    diffFile.println("<HTML>");
+                    diffFile.println("<HEAD>");
+                    diffFile.println("<meta name=\"generator\" content=\"JDiff v" + JDiff.version + "\">");
+                    diffFile.println("<!-- Generated by the JDiff Javadoc doclet -->");
+                    diffFile.println("<!-- (" + JDiff.jDiffLocation + ") -->");
+//                    diffFile.println("<!-- on " + new Date() + " -->");
+                    diffFile.println("<meta name=\"description\" content=\"" + JDiff.jDiffDescription + "\">");
+                    diffFile.println("<meta name=\"keywords\" content=\"" + JDiff.jDiffKeywords + "\">");
+                    diffFile.println("<LINK REL=\"stylesheet\" TYPE=\"text/css\" HREF=\"" + "../" + "stylesheet-jdiff.css\" TITLE=\"Style\">");
+                    diffFile.println("<TITLE>");
+                    diffFile.println(currPkgName + " Documentation Differences");
+                    diffFile.println("</TITLE>");
+                    diffFile.println("</HEAD>");
+                    diffFile.println("<BODY>");
+                                        
+                    // Write the navigation bar
+                    diffFile.println("<!-- Start of nav bar -->");
+                    diffFile.println("<TABLE summary=\"Navigation bar\" BORDER=\"0\" WIDTH=\"100%\" CELLPADDING=\"1\" CELLSPACING=\"0\">");
+                    diffFile.println("<TR>");
+                    diffFile.println("<TD COLSPAN=2 BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\">");
+                    diffFile.println("  <TABLE summary=\"Navigation bar\" BORDER=\"0\" CELLPADDING=\"0\" CELLSPACING=\"3\">");
+                    diffFile.println("    <TR ALIGN=\"center\" VALIGN=\"top\">");
+                    // Always have a link to the Javadoc files
+                    String pkgRef = currPkgName;
+                    pkgRef = pkgRef.replace('.', '/');
+                    pkgRef = HTMLReportGenerator.newDocPrefix + pkgRef + "/package-summary";
+                    diffFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + pkgRef + ".html\" target=\"_top\"><FONT CLASS=\"NavBarFont1\"><B><tt>" + APIDiff.newAPIName_ + "</tt></B></FONT></A>&nbsp;</TD>");
+                    diffFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + HTMLReportGenerator.reportFileName + "-summary" + HTMLReportGenerator.reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Overview</B></FONT></A>&nbsp;</TD>");
+                    diffFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> &nbsp;<FONT CLASS=\"NavBarFont1\">Package</FONT>&nbsp;</TD>");
+                    diffFile.println("      <TD BGCOLOR=\"#FFFFFF\" CLASS=\"NavBarCell1\"> &nbsp;<FONT CLASS=\"NavBarFont1\">Class</FONT>&nbsp;</TD>");
+                    if (!Diff.noDocDiffs) {
+                        diffFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + Diff.diffFileName + "index" + HTMLReportGenerator.reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Text Changes</B></FONT></A>&nbsp;</TD>");
+                    }
+                    if (HTMLReportGenerator.doStats) {
+                        diffFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"jdiff_statistics" + HTMLReportGenerator.reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Statistics</B></FONT></A>&nbsp;</TD>");
+                    }
+                    diffFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"jdiff_help" + HTMLReportGenerator.reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Help</B></FONT></A>&nbsp;</TD>");
+                    diffFile.println("    </TR>");
+                    diffFile.println("  </TABLE>");
+                    diffFile.println("</TD>");
+                    
+                    // The right hand side title
+                    diffFile.println("<TD ALIGN=\"right\" VALIGN=\"top\" ROWSPAN=3><EM><b>Generated by<br><a href=\"" + JDiff.jDiffLocation + "\" class=\"staysblack\" target=\"_top\">JDiff</a></b></EM></TD>");
+                    diffFile.println("</TR>");
+                    
+                    // Links for previous and next, and frames and no frames
+                    diffFile.println("<TR>");
+                    diffFile.println("  <TD BGCOLOR=\"" + HTMLReportGenerator.bgcolor + "\" CLASS=\"NavBarCell2\"><FONT SIZE=\"-2\">");
+                    if (prevPkgName != null)
+                        diffFile.println("  <A HREF=\"" + prevPkgName + "\"><B>PREV PACKAGE</B></A>  &nbsp;");
+                    else
+                        diffFile.println("  <B>PREV PACKAGE</B>  &nbsp;");
+                    if (nextPkgName != null)
+                        diffFile.println("  &nbsp;<A HREF=\"" + nextPkgName + "\"><B>NEXT PACKAGE</B></A>");
+                    else
+                        diffFile.println("  &nbsp;<B>NEXT PACKAGE</B>");
+                    diffFile.println("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
+                    diffFile.println("  <A HREF=\"" + "../" + HTMLReportGenerator.reportFileName + HTMLReportGenerator.reportFileExt + "\" TARGET=\"_top\"><B>FRAMES</B></A>  &nbsp;");
+                    diffFile.println("  &nbsp;<A HREF=\"" + diffFileName + currPkgName + HTMLReportGenerator.reportFileExt + "\" TARGET=\"_top\"><B>NO FRAMES</B></A></FONT></TD>");
+                    diffFile.println("  <TD BGCOLOR=\"" + HTMLReportGenerator.bgcolor + "\" CLASS=\"NavBarCell2\">&nbsp;</TD>");
+                    diffFile.println("</TR>");
+                    
+                    diffFile.println("</TABLE>");
+                    diffFile.println("<HR>");
+                    diffFile.println("<!-- End of nav bar -->");
+                    
+                    diffFile.println("<h2>");
+                    diffFile.println(currPkgName + " Documentation Differences");
+                    diffFile.println("</h2>");
+                    diffFile.println();
+                    diffFile.println("<blockquote>");
+                    diffFile.println("This file contains all the changes in documentation in the package <code>" + currPkgName + "</code> as colored differences.");
+                    if (deleteEffect == 0)
+                        diffFile.println("Deletions are shown <strike>like this</strike>, and");
+                    else if (deleteEffect == 1)
+                        diffFile.println("Deletions are shown <span style=\"background: #FFCCCC\">like this</span>, and");
+                    if (insertEffect == 0)
+                        diffFile.println("additions are shown in red <font color=\"red\">like this</font>.");
+                    else if (insertEffect == 1)
+                        diffFile.println("additions are shown <span style=\"background: #FFFF00\">like this</span>.");
+                    diffFile.println("</blockquote>");
+                    
+                    diffFile.println("<blockquote>");
+                    diffFile.println("If no deletions or additions are shown in an entry, the HTML tags will be what has changed. The <i>new</i> HTML tags are shown in the differences. ");
+                    diffFile.println("If no documentation existed, and then some was added in a later version, this change is noted in the appropriate class pages of differences, but the change is not shown on this page. Only changes in existing text are shown here. ");
+                    diffFile.println("Similarly, documentation which was inherited from another class or interface is not shown here.");
+                    diffFile.println("</blockquote>");
+                    
+                    diffFile.println("<blockquote>");
+                    diffFile.println(" Note that an HTML error in the new documentation may cause the display of other documentation changes to be presented incorrectly. For instance, failure to close a &lt;code&gt; tag will cause all subsequent paragraphs to be displayed differently.");
+                    diffFile.println("</blockquote>");
+                    diffFile.println("<hr>");
+                    diffFile.println();
+                    
+                } catch(IOException e) {
+                    System.out.println("IO Error while attempting to create " + fullDiffFileName);
+                    System.out.println("Error: " + e.getMessage());
+                    System.exit(1);
+                }
+            } // if (currPkgName == null || currPkgName.compareTo(diffOutput.pkgName_) != 0)
+            // Now add the documentation difference text
+            diffFile.println(diffOutput.text_);
+            // Separate with a horizontal line
+            if (i != docDiffsArr.length - 1 && 
+                diffOutput.className_ != null && 
+                docDiffsArr[i+1].className_ != null &&
+                diffOutput.className_.compareTo(docDiffsArr[i+1].className_) != 0)
+                diffFile.println("<hr align=\"left\" width=\"100%\">");
+//            else
+//                diffFile.println("<hr align=\"left\" width=\"50%\">");
+        } // for (i = 0;
+        if (currPkgName != null)
+            closeDiffFile(); // Close the existing file
+
+        // Emit the single file which is the index to all documentation changes
+        emitDocDiffIndex(fullReportFileName, docDiffsArr);
+    }
+
+    /** 
+     * Emit the single file which is the index to all documentation changes.
+     */
+    public static void emitDocDiffIndex(String fullReportFileName, 
+                                        DiffOutput[] docDiffsArr) { 
+
+        String fullDiffFileName = fullReportFileName + 
+            JDiff.DIR_SEP + diffFileName + "index" +
+            HTMLReportGenerator.reportFileExt;
+
+        // Create the output file
+        try {
+            FileOutputStream fos = new FileOutputStream(fullDiffFileName);
+            diffFile = new PrintWriter(fos);
+            
+            // Write the HTML header
+            diffFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Frameset//EN\"\"" + RootDocToXML.baseURI + "/TR/REC-html40/frameset.dtd\">");
+            diffFile.println("<HTML>");
+            diffFile.println("<HEAD>");
+            diffFile.println("<meta name=\"generator\" content=\"JDiff v" + JDiff.version + "\">");
+            diffFile.println("<!-- Generated by the JDiff Javadoc doclet -->");
+            diffFile.println("<!-- (" + JDiff.jDiffLocation + ") -->");
+//            diffFile.println("<!-- on " + new Date() + " -->");
+            diffFile.println("<meta name=\"description\" content=\"" + JDiff.jDiffDescription + "\">");
+            diffFile.println("<meta name=\"keywords\" content=\"" + JDiff.jDiffKeywords + "\">");
+            diffFile.println("<LINK REL=\"stylesheet\" TYPE=\"text/css\" HREF=\"" + "../" + "stylesheet-jdiff.css\" TITLE=\"Style\">");
+            diffFile.println("<TITLE>");
+            diffFile.println("All Documentation Differences");
+            diffFile.println("</TITLE>");
+            diffFile.println("</HEAD>");
+            diffFile.println("<BODY>");
+                        
+            // Write the navigation bar
+            diffFile.println("<!-- Start of nav bar -->");
+            diffFile.println("<TABLE summary=\"Navigation bar\" BORDER=\"0\" WIDTH=\"100%\" CELLPADDING=\"1\" CELLSPACING=\"0\">");
+            diffFile.println("<TR>");
+            diffFile.println("<TD COLSPAN=2 BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\">");
+            diffFile.println("  <TABLE summary=\"Navigation bar\" BORDER=\"0\" CELLPADDING=\"0\" CELLSPACING=\"3\">");
+            diffFile.println("    <TR ALIGN=\"center\" VALIGN=\"top\">");
+            // Always have a link to the Javadoc files
+            diffFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + HTMLReportGenerator.newDocPrefix + "index.html\" target=\"_top\"><FONT CLASS=\"NavBarFont1\"><B><tt>" + APIDiff.newAPIName_ + "</tt></B></FONT></A>&nbsp;</TD>");
+            diffFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + HTMLReportGenerator.reportFileName + "-summary" + HTMLReportGenerator.reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Overview</B></FONT></A>&nbsp;</TD>");
+            diffFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> &nbsp;<FONT CLASS=\"NavBarFont1\">Package</FONT>&nbsp;</TD>");
+            diffFile.println("      <TD BGCOLOR=\"#FFFFFF\" CLASS=\"NavBarCell1\"> &nbsp;<FONT CLASS=\"NavBarFont1\">Class</FONT>&nbsp;</TD>");
+            if (!Diff.noDocDiffs) {
+                diffFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1Rev\"> <FONT CLASS=\"NavBarFont1Rev\"><B>Text Changes</B></FONT>&nbsp;</TD>");
+            }
+            if (HTMLReportGenerator.doStats) {
+                diffFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"jdiff_statistics" + HTMLReportGenerator.reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Statistics</B></FONT></A>&nbsp;</TD>");
+            }
+            diffFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"jdiff_help" + HTMLReportGenerator.reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Help</B></FONT></A>&nbsp;</TD>");
+            diffFile.println("    </TR>");
+            diffFile.println("  </TABLE>");
+            diffFile.println("</TD>");
+            
+            // The right hand side title
+            diffFile.println("<TD ALIGN=\"right\" VALIGN=\"top\" ROWSPAN=3><EM><b>Generated by<br><a href=\"" + JDiff.jDiffLocation + "\" class=\"staysblack\" target=\"_top\">JDiff</a></b></EM></TD>");
+            diffFile.println("</TR>");
+            
+            // Links for frames and no frames
+            diffFile.println("<TR>");
+            diffFile.println("  <TD BGCOLOR=\"" + HTMLReportGenerator.bgcolor + "\" CLASS=\"NavBarCell2\"><FONT SIZE=\"-2\">");
+            diffFile.println("  <A HREF=\"" + "../" + HTMLReportGenerator.reportFileName + HTMLReportGenerator.reportFileExt + "\" TARGET=\"_top\"><B>FRAMES</B></A>  &nbsp;");
+            diffFile.println("  &nbsp;<A HREF=\"" + diffFileName + "index" + HTMLReportGenerator.reportFileExt + "\" TARGET=\"_top\"><B>NO FRAMES</B></A></FONT></TD>");
+            diffFile.println("  <TD BGCOLOR=\"" + HTMLReportGenerator.bgcolor + "\" CLASS=\"NavBarCell2\">&nbsp;</TD>");
+            diffFile.println("</TR>");
+            
+            diffFile.println("</TABLE>");
+            diffFile.println("<HR>");
+            diffFile.println("<!-- End of nav bar -->");
+            
+            diffFile.println("<h2>");
+            diffFile.println("All Documentation Differences");
+            diffFile.println("</h2>");
+            diffFile.println();
+            
+            // For each package and class, add the first DiffOutput to
+            // the hash table. Used when generating navigation bars.
+            boolean firstPackage = true; // Set for the first package
+            boolean firstClass = true; // Set for first class in a package
+            boolean firstCtor = true; // Set for first ctor in a class
+            boolean firstMethod = true; // Set for first method in a class
+            boolean firstField = true; // Set for first field in a class
+            for (int i = 0; i < docDiffsArr.length; i++) {
+                DiffOutput diffOutput = docDiffsArr[i];
+                String link = "<a href=\"" + Diff.diffFileName + diffOutput.pkgName_ + HTMLReportGenerator.reportFileExt + "#" + diffOutput.id_ + "\">";
+
+                // See if the package name changed
+                if (firstPackage || diffOutput.pkgName_.compareTo(docDiffsArr[i-1].pkgName_) != 0) {
+                    if (firstPackage) {
+                        firstPackage = false;
+                    } else {
+                        diffFile.println("<br>");
+                    }
+                    firstClass = true;
+                    firstCtor = true;
+                    firstMethod = true;
+                    firstField = true;
+                    String id = diffOutput.pkgName_ + "!package";
+                    firstDiffOutput.put(id, id);
+                    if (diffOutput.className_ == null) {
+                        diffFile.println("<A NAME=\"" + id + "\"></A>" + link + "Package <b>" + diffOutput.pkgName_ + "</b></a><br>");
+                    } else {
+                        diffFile.println("<A NAME=\"" + id + "\"></A>" + "Package <b>" + diffOutput.pkgName_ + "</b><br>");
+                    }
+                }
+                // See if the class name changed
+                if (diffOutput.className_ != null && 
+                    (firstClass || 
+                     diffOutput.className_.compareTo(docDiffsArr[i-1].className_) != 0)) {
+                    if (firstClass) {
+                        firstClass = false;
+                    } else {
+                        diffFile.println("<br>");
+                    }
+                    firstCtor = true;
+                    firstMethod = true;
+                    firstField = true;
+                    String id = diffOutput.pkgName_ + "." + diffOutput.className_ + "!class";
+                    firstDiffOutput.put(id, id);
+                    if (diffOutput.id_.endsWith("!class")) {
+                        diffFile.println("<A NAME=\"" + id + "\"></A>&nbsp;&nbsp;Class " + link + diffOutput.className_ + "</a><br>");
+                    } else {
+                        diffFile.println("<A NAME=\"" + id + "\"></A>&nbsp;&nbsp;Class " + diffOutput.className_ + "<br>");
+                    }
+                }
+                // Work out what kind of member this is, and
+                // display it appropriately
+                if (diffOutput.className_ != null && 
+                    !diffOutput.id_.endsWith("!class")) {
+                    int ctorIdx = diffOutput.id_.indexOf(".ctor");
+                    if (ctorIdx != -1) {
+                        diffFile.println("&nbsp;&nbsp;&nbsp;&nbsp;" + link + diffOutput.className_ + diffOutput.id_.substring(ctorIdx + 5) + "</a><br>");
+                    } else {
+                        int methodIdx = diffOutput.id_.indexOf(".dmethod.");
+                        if (methodIdx != -1) {
+                            diffFile.println("&nbsp;&nbsp;&nbsp;&nbsp;"  + "Method " + link + diffOutput.id_.substring(methodIdx + 9) + "</a><br>");
+                        } else {
+                            int fieldIdx = diffOutput.id_.indexOf(".field.");
+                            if (fieldIdx != -1) {
+                                diffFile.println("&nbsp;&nbsp;&nbsp;&nbsp;" + "Field " + link + diffOutput.id_.substring(fieldIdx + 7) + "</a><br>");
+                            }
+                        } //if (methodIdx != -1)
+                    } //if (ctorIdx != -1)
+                } //diffOutput.className_ != null
+            }
+        } catch(IOException e) {
+            System.out.println("IO Error while attempting to create " + fullDiffFileName);
+            System.out.println("Error: " + e.getMessage());
+            System.exit(1);
+        }
+        closeDiffFile();
+    }
+
+    /** 
+     * Emit the HTML footer and close the diff file. 
+     */
+    public static void closeDiffFile() { 
+        if (diffFile != null) {
+            // Write the HTML footer
+            diffFile.println();
+            diffFile.println("</BODY>");
+            diffFile.println("</HTML>");
+            diffFile.close();
+        }
+    }
+
+    /** 
+     * Current file where documentation differences are written as colored
+     * differences.
+     */
+    public static PrintWriter diffFile = null;
+
+    /** 
+     * Base name of the current file where documentation differences are 
+     * written as colored differences.
+     */
+    public static String diffFileName = "docdiffs_";
+
+    /** 
+     * The name of the current package, used to create diffFileName.
+     */
+    private static String currPkgName = null;
+
+    /** 
+     * If set, then do not generate colored diffs for documentation. 
+     * Default is true.
+     */
+    public static boolean noDocDiffs = true;
+
+    /** 
+     * Define the type of emphasis for deleted words.
+     * 0 strikes the words through.
+     * 1 outlines the words in light grey.
+     */
+    public static int deleteEffect = 0;
+
+    /** 
+     * Define the type of emphasis for inserted words.
+     * 0 colors the words red.
+     * 1 outlines the words in yellow, like a highlighter.
+     */
+    public static int insertEffect = 1;
+
+    /** 
+     * For each package and class, the first DiffOutput is added to
+     * this hash table. Used when generating navigation bars.
+     */
+    public static Hashtable firstDiffOutput = new Hashtable();
+
+    /** 
+     * If set, then show changes in implementation-related modifiers such as
+     * native and synchronized. For more information, see 
+     * http://java.sun.com/j2se/1.4.1/docs/tooldocs/solaris/javadoc.html#generatedapideclarations
+     */
+    public static boolean showAllChanges = false;
+
+    /** The list of documentation differences. */
+    private static List docDiffs = new ArrayList(); // DiffOutput[]
+        
+    /** Set to enable increased logging verbosity for debugging. */
+    private static boolean trace = false;
+        
+}  
diff --git a/src/jdiff/DiffMyers.java b/src/jdiff/DiffMyers.java
new file mode 100755
index 0000000..2e4683a
--- /dev/null
+++ b/src/jdiff/DiffMyers.java
@@ -0,0 +1,850 @@
+package jdiff;
+
+import java.io.*;
+import java.util.*;
+
+/** A class to compare vectors of objects.  The result of comparison
+    is a list of <code>change</code> objects which form an
+    edit script.  The objects compared are traditionally lines
+    of text from two files.  Comparison options such as "ignore
+    whitespace" are implemented by modifying the <code>equals</code>
+    and <code>hashcode</code> methods for the objects compared.
+<p>
+   The basic algorithm is described in: </br>
+   "An O(ND) Difference Algorithm and its Variations", Eugene Myers,
+   Algorithmica Vol. 1 No. 2, 1986, p 251.  
+<p>
+   This class outputs different results from GNU diff 1.15 on some
+   inputs.  Our results are actually better (smaller change list, smaller
+   total size of changes), but it would be nice to know why.  Perhaps
+   there is a memory overwrite bug in GNU diff 1.15.
+
+  @author Stuart D. Gathman, translated from GNU diff 1.15
+    Copyright (C) 2000  Business Management Systems, Inc.
+<p>
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 1, or (at your option)
+    any later version.
+<p>
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+<p>
+    You should have received a copy of the <a href=COPYING.txt>
+    GNU General Public License</a>
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+public class DiffMyers
+{
+
+  /** Prepare to find differences between two arrays.  Each element of
+      the arrays is translated to an "equivalence number" based on
+      the result of <code>equals</code>.  The original Object arrays
+      are no longer needed for computing the differences.  They will
+      be needed again later to print the results of the comparison as
+      an edit script, if desired.
+   */
+  public DiffMyers(Object[] a,Object[] b)
+  {
+    Hashtable h = new Hashtable(a.length + b.length);
+    filevec[0] = new file_data(a,h);
+    filevec[1] = new file_data(b,h);
+  }
+
+  /** 1 more than the maximum equivalence value used for this or its
+     sibling file. */
+  private int equiv_max = 1;
+
+  /** When set to true, the comparison uses a heuristic to speed it up.
+    With this heuristic, for files with a constant small density
+    of changes, the algorithm is linear in the file size.  */
+  public boolean heuristic = false;
+
+  /** When set to true, the algorithm returns a guarranteed minimal
+      set of changes.  This makes things slower, sometimes much slower. */
+  public boolean no_discards = false;
+
+  private int[] xvec, yvec;        /* Vectors being compared. */
+  private int[] fdiag;                /* Vector, indexed by diagonal, containing
+                                   the X coordinate of the point furthest
+                                   along the given diagonal in the forward
+                                   search of the edit matrix. */
+  private int[] bdiag;                /* Vector, indexed by diagonal, containing
+                                   the X coordinate of the point furthest
+                                   along the given diagonal in the backward
+                                   search of the edit matrix. */
+  private int fdiagoff, bdiagoff;
+  private final file_data[] filevec = new file_data[2];
+  private int cost;
+
+  /** Find the midpoint of the shortest edit script for a specified
+     portion of the two files.
+
+     We scan from the beginnings of the files, and simultaneously from the ends,
+     doing a breadth-first search through the space of edit-sequence.
+     When the two searches meet, we have found the midpoint of the shortest
+     edit sequence.
+
+     The value returned is the number of the diagonal on which the midpoint lies.
+     The diagonal number equals the number of inserted lines minus the number
+     of deleted lines (counting only lines before the midpoint).
+     The edit cost is stored into COST; this is the total number of
+     lines inserted or deleted (counting only lines before the midpoint).
+
+     This function assumes that the first lines of the specified portions
+     of the two files do not match, and likewise that the last lines do not
+     match.  The caller must trim matching lines from the beginning and end
+     of the portions it is going to specify.
+
+     Note that if we return the "wrong" diagonal value, or if
+     the value of bdiag at that diagonal is "wrong",
+     the worst this can do is cause suboptimal diff output.
+     It cannot cause incorrect diff output.  */
+
+  private int diag (int xoff, int xlim, int yoff, int ylim)
+  {
+    final int[] fd = fdiag;        // Give the compiler a chance.
+    final int[] bd = bdiag;        // Additional help for the compiler.
+    final int[] xv = xvec;                // Still more help for the compiler.
+    final int[] yv = yvec;                // And more and more . . .
+    final int dmin = xoff - ylim;        // Minimum valid diagonal.
+    final int dmax = xlim - yoff;        // Maximum valid diagonal.
+    final int fmid = xoff - yoff;        // Center diagonal of top-down search.
+    final int bmid = xlim - ylim;        // Center diagonal of bottom-up search.
+    int fmin = fmid, fmax = fmid;        // Limits of top-down search.
+    int bmin = bmid, bmax = bmid;        // Limits of bottom-up search.
+    /* True if southeast corner is on an odd
+                                     diagonal with respect to the northwest. */
+    final boolean odd = (fmid - bmid & 1) != 0;        
+
+    fd[fdiagoff + fmid] = xoff;
+    bd[bdiagoff + bmid] = xlim;
+
+    for (int c = 1;; ++c)
+      {
+        int d;                        /* Active diagonal. */
+        boolean big_snake = false;
+
+        /* Extend the top-down search by an edit step in each diagonal. */
+        if (fmin > dmin)
+          fd[fdiagoff + --fmin - 1] = -1;
+        else
+          ++fmin;
+        if (fmax < dmax)
+          fd[fdiagoff + ++fmax + 1] = -1;
+        else
+          --fmax;
+        for (d = fmax; d >= fmin; d -= 2)
+          {
+            int x, y, oldx, tlo = fd[fdiagoff + d - 1], thi = fd[fdiagoff + d + 1];
+
+            if (tlo >= thi)
+              x = tlo + 1;
+            else
+              x = thi;
+            oldx = x;
+            y = x - d;
+            while (x < xlim && y < ylim && xv[x] == yv[y]) {
+              ++x; ++y;
+            }
+            if (x - oldx > 20)
+              big_snake = true;
+            fd[fdiagoff + d] = x;
+            if (odd && bmin <= d && d <= bmax && bd[bdiagoff + d] <= fd[fdiagoff + d])
+              {
+                cost = 2 * c - 1;
+                return d;
+              }
+          }
+
+        /* Similar extend the bottom-up search. */
+        if (bmin > dmin)
+          bd[bdiagoff + --bmin - 1] = Integer.MAX_VALUE;
+        else
+          ++bmin;
+        if (bmax < dmax)
+          bd[bdiagoff + ++bmax + 1] = Integer.MAX_VALUE;
+        else
+          --bmax;
+        for (d = bmax; d >= bmin; d -= 2)
+          {
+            int x, y, oldx, tlo = bd[bdiagoff + d - 1], thi = bd[bdiagoff + d + 1];
+
+            if (tlo < thi)
+              x = tlo;
+            else
+              x = thi - 1;
+            oldx = x;
+            y = x - d;
+            while (x > xoff && y > yoff && xv[x - 1] == yv[y - 1]) {
+              --x; --y;
+            }
+            if (oldx - x > 20)
+              big_snake = true;
+            bd[bdiagoff + d] = x;
+            if (!odd && fmin <= d && d <= fmax && bd[bdiagoff + d] <= fd[fdiagoff + d])
+              {
+                cost = 2 * c;
+                return d;
+              }
+          }
+
+        /* Heuristic: check occasionally for a diagonal that has made
+           lots of progress compared with the edit distance.
+           If we have any such, find the one that has made the most
+           progress and return it as if it had succeeded.
+
+           With this heuristic, for files with a constant small density
+           of changes, the algorithm is linear in the file size.  */
+
+        if (c > 200 && big_snake && heuristic)
+          {
+            int best = 0;
+            int bestpos = -1;
+
+            for (d = fmax; d >= fmin; d -= 2)
+              {
+                int dd = d - fmid;
+                if ((fd[fdiagoff + d] - xoff)*2 - dd > 12 * (c + (dd > 0 ? dd : -dd)))
+                  {
+                    if (fd[fdiagoff + d] * 2 - dd > best
+                        && fd[fdiagoff + d] - xoff > 20
+                        && fd[fdiagoff + d] - d - yoff > 20)
+                      {
+                        int k;
+                        int x = fd[fdiagoff + d];
+
+                        /* We have a good enough best diagonal;
+                           now insist that it end with a significant snake.  */
+                        for (k = 1; k <= 20; k++)
+                          if (xvec[x - k] != yvec[x - d - k])
+                            break;
+
+                        if (k == 21)
+                          {
+                            best = fd[fdiagoff + d] * 2 - dd;
+                            bestpos = d;
+                          }
+                      }
+                  }
+              }
+            if (best > 0)
+              {
+                cost = 2 * c - 1;
+                return bestpos;
+              }
+
+            best = 0;
+            for (d = bmax; d >= bmin; d -= 2)
+              {
+                int dd = d - bmid;
+                if ((xlim - bd[bdiagoff + d])*2 + dd > 12 * (c + (dd > 0 ? dd : -dd)))
+                  {
+                    if ((xlim - bd[bdiagoff + d]) * 2 + dd > best
+                        && xlim - bd[bdiagoff + d] > 20
+                        && ylim - (bd[bdiagoff + d] - d) > 20)
+                      {
+                        /* We have a good enough best diagonal;
+                           now insist that it end with a significant snake.  */
+                        int k;
+                        int x = bd[bdiagoff + d];
+
+                        for (k = 0; k < 20; k++)
+                          if (xvec[x + k] != yvec[x - d + k])
+                            break;
+                        if (k == 20)
+                          {
+                            best = (xlim - bd[bdiagoff + d]) * 2 + dd;
+                            bestpos = d;
+                          }
+                      }
+                  }
+              }
+            if (best > 0)
+              {
+                cost = 2 * c - 1;
+                return bestpos;
+              }
+          }
+      }
+  }
+
+  /** Compare in detail contiguous subsequences of the two files
+     which are known, as a whole, to match each other.
+
+     The results are recorded in the vectors filevec[N].changed_flag, by
+     storing a 1 in the element for each line that is an insertion or deletion.
+
+     The subsequence of file 0 is [XOFF, XLIM) and likewise for file 1.
+
+     Note that XLIM, YLIM are exclusive bounds.
+     All line numbers are origin-0 and discarded lines are not counted.  */
+
+  private void compareseq (int xoff, int xlim, int yoff, int ylim) {
+    /* Slide down the bottom initial diagonal. */
+    while (xoff < xlim && yoff < ylim && xvec[xoff] == yvec[yoff]) {
+      ++xoff; ++yoff;
+    }
+    /* Slide up the top initial diagonal. */
+    while (xlim > xoff && ylim > yoff && xvec[xlim - 1] == yvec[ylim - 1]) {
+      --xlim; --ylim;
+    }
+    
+    /* Handle simple cases. */
+    if (xoff == xlim)
+      while (yoff < ylim)
+        filevec[1].changed_flag[1+filevec[1].realindexes[yoff++]] = true;
+    else if (yoff == ylim)
+      while (xoff < xlim)
+        filevec[0].changed_flag[1+filevec[0].realindexes[xoff++]] = true;
+    else
+      {
+        /* Find a point of correspondence in the middle of the files.  */
+
+        int d = diag (xoff, xlim, yoff, ylim);
+        int c = cost;
+        int f = fdiag[fdiagoff + d];
+        int b = bdiag[bdiagoff + d];
+
+        if (c == 1)
+          {
+            /* This should be impossible, because it implies that
+               one of the two subsequences is empty,
+               and that case was handled above without calling `diag'.
+               Let's verify that this is true.  */
+            throw new IllegalArgumentException("Empty subsequence");
+          }
+        else
+          {
+            /* Use that point to split this problem into two subproblems.  */
+            compareseq (xoff, b, yoff, b - d);
+            /* This used to use f instead of b,
+               but that is incorrect!
+               It is not necessarily the case that diagonal d
+               has a snake from b to f.  */
+            compareseq (b, xlim, b - d, ylim);
+          }
+      }
+  }
+
+  /** Discard lines from one file that have no matches in the other file.
+   */
+
+  private void discard_confusing_lines() {
+    filevec[0].discard_confusing_lines(filevec[1]);
+    filevec[1].discard_confusing_lines(filevec[0]);
+  }
+
+  private boolean inhibit = false;
+
+  /** Adjust inserts/deletes of blank lines to join changes
+     as much as possible.
+   */
+
+  private void shift_boundaries() {
+    if (inhibit)
+      return;
+    filevec[0].shift_boundaries(filevec[1]);
+    filevec[1].shift_boundaries(filevec[0]);
+  }
+
+  /** Scan the tables of which lines are inserted and deleted,
+     producing an edit script in reverse order.  */
+
+  private change build_reverse_script() {
+    change script = null;
+    final boolean[] changed0 = filevec[0].changed_flag;
+    final boolean[] changed1 = filevec[1].changed_flag;
+    final int len0 = filevec[0].buffered_lines;
+    final int len1 = filevec[1].buffered_lines;
+
+    /* Note that changedN[len0] does exist, and contains 0.  */
+
+    int i0 = 0, i1 = 0;
+
+    while (i0 < len0 || i1 < len1)
+      {
+        if (changed0[1+i0] || changed1[1+i1])
+          {
+            int line0 = i0, line1 = i1;
+
+            /* Find # lines changed here in each file.  */
+            while (changed0[1+i0]) ++i0;
+            while (changed1[1+i1]) ++i1;
+
+            /* Record this change.  */
+            script = new change(line0, line1, i0 - line0, i1 - line1, script);
+          }
+
+        /* We have reached lines in the two files that match each other.  */
+        i0++; i1++;
+      }
+
+    return script;
+  }
+
+  /** Scan the tables of which lines are inserted and deleted,
+     producing an edit script in forward order.  */
+
+  private change build_script() {
+    change script = null;
+    final boolean[] changed0 = filevec[0].changed_flag;
+    final boolean[] changed1 = filevec[1].changed_flag;
+    final int len0 = filevec[0].buffered_lines;
+    final int len1 = filevec[1].buffered_lines;
+    int i0 = len0, i1 = len1;
+
+    /* Note that changedN[-1] does exist, and contains 0.  */
+
+    while (i0 >= 0 || i1 >= 0)
+      {
+        if (changed0[i0] || changed1[i1])
+          {
+            int line0 = i0, line1 = i1;
+
+            /* Find # lines changed here in each file.  */
+            while (changed0[i0]) --i0;
+            while (changed1[i1]) --i1;
+
+            /* Record this change.  */
+            script = new change(i0, i1, line0 - i0, line1 - i1, script);
+          }
+
+        /* We have reached lines in the two files that match each other.  */
+        i0--; i1--;
+      }
+
+    return script;
+  }
+
+  /* Report the differences of two files.  DEPTH is the current directory
+     depth. */
+  public change diff_2(final boolean reverse) {
+
+    /* Some lines are obviously insertions or deletions
+       because they don't match anything.  Detect them now,
+       and avoid even thinking about them in the main comparison algorithm.  */
+
+    discard_confusing_lines ();
+
+    /* Now do the main comparison algorithm, considering just the
+       undiscarded lines.  */
+
+    xvec = filevec[0].undiscarded;
+    yvec = filevec[1].undiscarded;
+
+    int diags =
+      filevec[0].nondiscarded_lines + filevec[1].nondiscarded_lines + 3;
+    fdiag = new int[diags];
+    fdiagoff = filevec[1].nondiscarded_lines + 1;
+    bdiag = new int[diags];
+    bdiagoff = filevec[1].nondiscarded_lines + 1;
+
+    compareseq (0, filevec[0].nondiscarded_lines,
+                0, filevec[1].nondiscarded_lines);
+    fdiag = null;
+    bdiag = null;
+
+    /* Modify the results slightly to make them prettier
+       in cases where that can validly be done.  */
+
+    shift_boundaries ();
+
+    /* Get the results of comparison in the form of a chain
+       of `struct change's -- an edit script.  */
+
+    if (reverse)
+      return build_reverse_script();
+    else
+      return build_script();
+  }
+
+  /** The result of comparison is an "edit script": a chain of change objects.
+     Each change represents one place where some lines are deleted
+     and some are inserted.
+     
+     LINE0 and LINE1 are the first affected lines in the two files (origin 0).
+     DELETED is the number of lines deleted here from file 0.
+     INSERTED is the number of lines inserted here in file 1.
+
+     If DELETED is 0 then LINE0 is the number of the line before
+     which the insertion was done; vice versa for INSERTED and LINE1.  */
+
+  public static class change {
+    /** Previous or next edit command. */
+    public change link;                
+    /** # lines of file 1 changed here.  */
+    public int inserted;        
+    /** # lines of file 0 changed here.  */
+    public int deleted;                
+    /** Line number of 1st deleted line.  */
+    public final int line0;                
+    /** Line number of 1st inserted line.  */
+    public final int line1;                
+
+    /** Cons an additional entry onto the front of an edit script OLD.
+       LINE0 and LINE1 are the first affected lines in the two files (origin 0).
+       DELETED is the number of lines deleted here from file 0.
+       INSERTED is the number of lines inserted here in file 1.
+
+       If DELETED is 0 then LINE0 is the number of the line before
+       which the insertion was done; vice versa for INSERTED and LINE1.  */
+    change(int line0, int line1, int deleted, int inserted, change old) {
+      this.line0 = line0;
+      this.line1 = line1;
+      this.inserted = inserted;
+      this.deleted = deleted;
+      this.link = old;
+      //System.err.println(line0+","+line1+","+inserted+","+deleted);
+    }
+  }
+
+  /** Data on one input file being compared.  
+   */
+
+  class file_data {
+
+    /** Allocate changed array for the results of comparison.  */
+    void clear() {
+      /* Allocate a flag for each line of each file, saying whether that line
+         is an insertion or deletion.
+         Allocate an extra element, always zero, at each end of each vector.
+       */
+      changed_flag = new boolean[buffered_lines + 2];
+    }
+
+    /** Return equiv_count[I] as the number of lines in this file
+       that fall in equivalence class I.
+         @return the array of equivalence class counts.
+     */
+    int[] equivCount() {
+      int[] equiv_count = new int[equiv_max];
+      for (int i = 0; i < buffered_lines; ++i)
+        ++equiv_count[equivs[i]];
+      return equiv_count;
+    }
+
+    /** Discard lines that have no matches in another file.
+
+       A line which is discarded will not be considered by the actual
+       comparison algorithm; it will be as if that line were not in the file.
+       The file's `realindexes' table maps virtual line numbers
+       (which don't count the discarded lines) into real line numbers;
+       this is how the actual comparison algorithm produces results
+       that are comprehensible when the discarded lines are counted.
+<p>
+       When we discard a line, we also mark it as a deletion or insertion
+       so that it will be printed in the output.  
+      @param f the other file   
+     */
+    void discard_confusing_lines(file_data f) {
+      clear();
+    /* Set up table of which lines are going to be discarded. */
+      final byte[] discarded = discardable(f.equivCount());
+
+    /* Don't really discard the provisional lines except when they occur
+       in a run of discardables, with nonprovisionals at the beginning
+       and end.  */
+      filterDiscards(discarded);
+
+    /* Actually discard the lines. */
+      discard(discarded);
+    }
+
+    /** Mark to be discarded each line that matches no line of another file.
+       If a line matches many lines, mark it as provisionally discardable.  
+       @see equivCount()
+       @param counts The count of each equivalence number for the other file.
+       @return 0=nondiscardable, 1=discardable or 2=provisionally discardable
+               for each line
+     */
+
+    private byte[] discardable(final int[] counts) {
+      final int end = buffered_lines;
+      final byte[] discards = new byte[end];
+      final int[] equivs = this.equivs;
+      int many = 5;
+      int tem = end / 64;
+
+      /* Multiply MANY by approximate square root of number of lines.
+         That is the threshold for provisionally discardable lines.  */
+      while ((tem = tem >> 2) > 0)
+        many *= 2;
+
+      for (int i = 0; i < end; i++)
+        {
+          int nmatch;
+          if (equivs[i] == 0)
+            continue;
+          nmatch = counts[equivs[i]];
+          if (nmatch == 0)
+            discards[i] = 1;
+          else if (nmatch > many)
+            discards[i] = 2;
+        }
+      return discards;
+    }
+
+    /** Don't really discard the provisional lines except when they occur
+       in a run of discardables, with nonprovisionals at the beginning
+       and end.  */
+
+    private void filterDiscards(final byte[] discards) {
+        final int end = buffered_lines;
+
+        for (int i = 0; i < end; i++)
+          {
+            /* Cancel provisional discards not in middle of run of discards.  */
+            if (discards[i] == 2)
+              discards[i] = 0;
+            else if (discards[i] != 0)
+              {
+                /* We have found a nonprovisional discard.  */
+                int j;
+                int length;
+                int provisional = 0;
+
+                /* Find end of this run of discardable lines.
+                   Count how many are provisionally discardable.  */
+                for (j = i; j < end; j++)
+                  {
+                    if (discards[j] == 0)
+                      break;
+                    if (discards[j] == 2)
+                      ++provisional;
+                  }
+
+                /* Cancel provisional discards at end, and shrink the run.  */
+                while (j > i && discards[j - 1] == 2) {
+                  discards[--j] = 0; --provisional;
+                }
+
+                /* Now we have the length of a run of discardable lines
+                   whose first and last are not provisional.  */
+                length = j - i;
+
+                /* If 1/4 of the lines in the run are provisional,
+                   cancel discarding of all provisional lines in the run.  */
+                if (provisional * 4 > length)
+                  {
+                    while (j > i)
+                      if (discards[--j] == 2)
+                        discards[j] = 0;
+                  }
+                else
+                  {
+                    int consec;
+                    int minimum = 1;
+                    int tem = length / 4;
+
+                    /* MINIMUM is approximate square root of LENGTH/4.
+                       A subrun of two or more provisionals can stand
+                       when LENGTH is at least 16.
+                       A subrun of 4 or more can stand when LENGTH >= 64.  */
+                    while ((tem = tem >> 2) > 0)
+                      minimum *= 2;
+                    minimum++;
+
+                    /* Cancel any subrun of MINIMUM or more provisionals
+                       within the larger run.  */
+                    for (j = 0, consec = 0; j < length; j++)
+                      if (discards[i + j] != 2)
+                        consec = 0;
+                      else if (minimum == ++consec)
+                        /* Back up to start of subrun, to cancel it all.  */
+                        j -= consec;
+                      else if (minimum < consec)
+                        discards[i + j] = 0;
+
+                    /* Scan from beginning of run
+                       until we find 3 or more nonprovisionals in a row
+                       or until the first nonprovisional at least 8 lines in.
+                       Until that point, cancel any provisionals.  */
+                    for (j = 0, consec = 0; j < length; j++)
+                      {
+                        if (j >= 8 && discards[i + j] == 1)
+                          break;
+                        if (discards[i + j] == 2) {
+                          consec = 0; discards[i + j] = 0;
+                        }
+                        else if (discards[i + j] == 0)
+                          consec = 0;
+                        else
+                          consec++;
+                        if (consec == 3)
+                          break;
+                      }
+
+                    /* I advances to the last line of the run.  */
+                    i += length - 1;
+
+                    /* Same thing, from end.  */
+                    for (j = 0, consec = 0; j < length; j++)
+                      {
+                        if (j >= 8 && discards[i - j] == 1)
+                          break;
+                        if (discards[i - j] == 2) {
+                          consec = 0; discards[i - j] = 0;
+                        }
+                        else if (discards[i - j] == 0)
+                          consec = 0;
+                        else
+                          consec++;
+                        if (consec == 3)
+                          break;
+                      }
+                  }
+              }
+          }
+      }
+
+    /** Actually discard the lines.
+      @param discards flags lines to be discarded
+     */
+    private void discard(final byte[] discards) {
+      final int end = buffered_lines;
+      int j = 0;
+      for (int i = 0; i < end; ++i)
+        if (no_discards || discards[i] == 0)
+          {
+            undiscarded[j] = equivs[i];
+            realindexes[j++] = i;
+          }
+        else
+          changed_flag[1+i] = true;
+      nondiscarded_lines = j;
+    }
+
+    file_data(Object[] data,Hashtable h) {
+      buffered_lines = data.length;
+
+      equivs = new int[buffered_lines]; 
+      undiscarded = new int[buffered_lines];
+      realindexes = new int[buffered_lines];
+
+      for (int i = 0; i < data.length; ++i) {
+        Integer ir = (Integer)h.get(data[i]);
+        if (ir == null)
+          h.put(data[i],new Integer(equivs[i] = equiv_max++));
+        else
+          equivs[i] = ir.intValue();
+      }
+    }
+
+    /** Adjust inserts/deletes of blank lines to join changes
+       as much as possible.
+
+       We do something when a run of changed lines include a blank
+       line at one end and have an excluded blank line at the other.
+       We are free to choose which blank line is included.
+       `compareseq' always chooses the one at the beginning,
+       but usually it is cleaner to consider the following blank line
+       to be the "change".  The only exception is if the preceding blank line
+       would join this change to other changes.  
+      @param f the file being compared against
+    */
+
+    void shift_boundaries(file_data f) {
+      final boolean[] changed = changed_flag;
+      final boolean[] other_changed = f.changed_flag;
+      int i = 0;
+      int j = 0;
+      int i_end = buffered_lines;
+      int preceding = -1;
+      int other_preceding = -1;
+
+      for (;;)
+        {
+          int start, end, other_start;
+
+          /* Scan forwards to find beginning of another run of changes.
+             Also keep track of the corresponding point in the other file.  */
+
+          while (i < i_end && !changed[1+i])
+            {
+              while (other_changed[1+j++])
+                /* Non-corresponding lines in the other file
+                   will count as the preceding batch of changes.  */
+                other_preceding = j;
+              i++;
+            }
+
+          if (i == i_end)
+            break;
+
+          start = i;
+          other_start = j;
+
+          for (;;)
+            {
+              /* Now find the end of this run of changes.  */
+
+              while (i < i_end && changed[1+i]) i++;
+              end = i;
+
+              /* If the first changed line matches the following unchanged one,
+                 and this run does not follow right after a previous run,
+                 and there are no lines deleted from the other file here,
+                 then classify the first changed line as unchanged
+                 and the following line as changed in its place.  */
+
+              /* You might ask, how could this run follow right after another?
+                 Only because the previous run was shifted here.  */
+
+              if (end != i_end
+                  && equivs[start] == equivs[end]
+                  && !other_changed[1+j]
+                  && end != i_end
+                  && !((preceding >= 0 && start == preceding)
+                       || (other_preceding >= 0
+                           && other_start == other_preceding)))
+                {
+                  changed[1+end++] = true;
+                  changed[1+start++] = false;
+                  ++i;
+                  /* Since one line-that-matches is now before this run
+                     instead of after, we must advance in the other file
+                     to keep in synch.  */
+                  ++j;
+                }
+              else
+                break;
+            }
+
+          preceding = i;
+          other_preceding = j;
+        }
+    }
+
+    /** Number of elements (lines) in this file. */
+    final int buffered_lines;
+
+    /** Vector, indexed by line number, containing an equivalence code for
+       each line.  It is this vector that is actually compared with that
+       of another file to generate differences. */
+    private final int[]            equivs;
+
+    /** Vector, like the previous one except that
+       the elements for discarded lines have been squeezed out.  */
+    final int[]           undiscarded;
+
+    /** Vector mapping virtual line numbers (not counting discarded lines)
+       to real ones (counting those lines).  Both are origin-0.  */
+    final int[]           realindexes;
+
+    /** Total number of nondiscarded lines. */
+    int                    nondiscarded_lines;
+
+    /** Array, indexed by real origin-1 line number,
+       containing true for a line that is an insertion or a deletion.
+       The results of comparison are stored here.  */
+    boolean[]            changed_flag;
+
+  }    
+    
+}
diff --git a/src/jdiff/DiffOutput.java b/src/jdiff/DiffOutput.java
new file mode 100755
index 0000000..9b2c13c
--- /dev/null
+++ b/src/jdiff/DiffOutput.java
@@ -0,0 +1,54 @@
+package jdiff;
+
+import java.io.*;
+import java.util.*;
+
+/** 
+ * Class to represent a single documentation difference.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+class DiffOutput implements Comparable {
+
+    /** The package name for this difference. */
+    public String pkgName_ = null;
+
+    /** The class name for this difference, may be null. */
+    public String className_ = null;
+
+    /** The HTML named anchor identifier for this difference. */
+    public String id_ = null;
+
+    /** The title for this difference. */
+    public String title_ = null;
+
+    /** The text for this difference, with deleted and added words marked. */
+    public String text_ = null;
+
+    /** Constructor. */
+    public DiffOutput(String pkgName, String className, String id, 
+                      String title, String text) {
+        pkgName_ = pkgName;
+        className_ = className;
+        id_ = id;
+        title_ = title;
+        text_ = text;
+    }
+
+    /** 
+     * Compare two DiffOutput objects, so they will appear in the correct
+     * package. 
+     */
+    public int compareTo(Object o) {
+        DiffOutput oDiffOutput = (DiffOutput)o;
+        int comp = pkgName_.compareTo(oDiffOutput.pkgName_);
+        if (comp != 0)
+            return comp;
+        // Always put the package-level output at the top - not yet working
+//        if (id_.compareTo("package") == 0)
+//            return -1;
+        return id_.compareTo(oDiffOutput.id_);
+    }    
+        
+}  
diff --git a/src/jdiff/FieldAPI.java b/src/jdiff/FieldAPI.java
new file mode 100755
index 0000000..151e729
--- /dev/null
+++ b/src/jdiff/FieldAPI.java
@@ -0,0 +1,107 @@
+package jdiff;
+
+import java.io.*;
+import java.util.*;
+
+/** 
+ * Class to represent a field, analogous to FieldDoc in the 
+ * Javadoc doclet API. 
+ * 
+ * The method used for Collection comparison (compareTo) must make its
+ * comparison based upon everything that is known about this field.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+class FieldAPI implements Comparable {
+    /** Name of the field. */
+    public String name_;
+
+    /** Type of the field. */
+    public String type_;
+
+    /** 
+     * The fully qualified name of the class or interface this field is
+     * inherited from. If this is null, then the field is defined locally 
+     * in this class or interface.
+     */
+    public String inheritedFrom_ = null;
+
+    /** Set if this field is transient. */
+    public boolean isTransient_ = false;
+
+    /** Set if this field is volatile. */
+    public boolean isVolatile_ = false;
+
+    /** If non-null, this is the value of this field. */
+    public String value_ = null;
+
+    /** Modifiers for this class. */
+    public Modifiers modifiers_;
+
+    /** The doc block, default is null. */
+    public String doc_ = null;
+
+    /** Constructor. */
+    public FieldAPI(String name, String type, 
+                    boolean isTransient, boolean isVolatile, 
+                    String value, Modifiers modifiers) {
+        name_ = name;
+        type_ = type;
+        isTransient_ = isTransient;
+        isVolatile_ = isVolatile;
+        value_ = value;
+        modifiers_ = modifiers;
+    }
+
+    /** Copy constructor. */
+    public FieldAPI(FieldAPI f) {
+        name_ = f.name_;
+        type_ = f.type_;
+        inheritedFrom_ = f.inheritedFrom_;
+        isTransient_ = f.isTransient_;
+        isVolatile_ = f.isVolatile_;
+        value_ = f.value_;
+        modifiers_ = f.modifiers_; // Note: shallow copy
+        doc_ = f.doc_;
+    }
+
+    /** Compare two FieldAPI objects, including name, type and modifiers. */
+    public int compareTo(Object o) {
+        FieldAPI oFieldAPI = (FieldAPI)o;
+        int comp = name_.compareTo(oFieldAPI.name_);
+        if (comp != 0)
+            return comp;
+        comp = type_.compareTo(oFieldAPI.type_);
+        if (comp != 0)
+            return comp;
+        if (APIComparator.changedInheritance(inheritedFrom_, oFieldAPI.inheritedFrom_) != 0)
+            return -1;
+        if (isTransient_ != oFieldAPI.isTransient_) {
+            return -1;
+        }
+        if (isVolatile_ != oFieldAPI.isVolatile_) {
+            return -1;
+        }
+        if (value_ != null && oFieldAPI.value_ != null) {
+            comp = value_.compareTo(oFieldAPI.value_);
+            if (comp != 0)
+                return comp;
+        }
+        comp = modifiers_.compareTo(oFieldAPI.modifiers_);
+        if (comp != 0)
+            return comp;
+        if (APIComparator.docChanged(doc_, oFieldAPI.doc_))
+            return -1;
+        return 0;
+    }
+  
+    /** 
+     * Tests two fields, using just the field name, used by indexOf().
+     */
+    public boolean equals(Object o) {
+        if (name_.compareTo(((FieldAPI)o).name_) == 0)
+            return true;
+        return false;
+    }
+}  
diff --git a/src/jdiff/HTMLFiles.java b/src/jdiff/HTMLFiles.java
new file mode 100755
index 0000000..a141e6c
--- /dev/null
+++ b/src/jdiff/HTMLFiles.java
@@ -0,0 +1,368 @@
+package jdiff;
+
+import java.util.*;
+import java.io.*;
+
+/**
+ * Emit HTML files for the supporting infrastructure for the HTML report.
+ * Examples are stylesheets, help files, frame files.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+public class HTMLFiles {
+
+    /** Constructor. */
+    public HTMLFiles(HTMLReportGenerator h) {
+        h_ = h;
+    }   
+
+    /** The HTMLReportGenerator instance used to write HTML. */
+    private HTMLReportGenerator h_ = null;
+
+    /** 
+     * Emit the top-level changes.html frames file where everything starts.
+     */
+    public void emitTopLevelFile(String tln,
+                                 APIDiff apiDiff) {
+        try {
+            FileOutputStream fos = new FileOutputStream(tln);
+            h_.reportFile = new PrintWriter(fos);
+            // Write out the HTML header
+            h_.writeStartHTMLHeaderWithDate();
+            // Write out the title
+            String oldAPIName = "Old API";
+            if (apiDiff.oldAPIName_ != null)
+                oldAPIName = apiDiff.oldAPIName_;
+            String newAPIName = "New API";
+            if (apiDiff.newAPIName_ != null)
+                newAPIName = apiDiff.newAPIName_;
+            if (h_.windowTitle == null) 
+                h_.writeHTMLTitle("API Differences between " + oldAPIName + " and " + newAPIName);
+            else
+                h_.writeHTMLTitle(h_.windowTitle);
+            // Note that the stylesheet is in the same directory
+            h_.writeStyleSheetRef(true);
+            h_.writeText("</HEAD>");
+            // Note that the top-level frame file doesn't have the BODY tag
+            h_.writeText("<FRAMESET COLS=\"20%,80%\">");
+            h_.writeText("<frameset rows=\"196,**\">");
+
+            // Convert filenames to web links
+            String tlfLink = h_.reportFileName + "/jdiff_topleftframe" + h_.reportFileExt;
+            String allDiffsLink = h_.reportFileName + "/alldiffs_index_all" + h_.reportFileExt;
+            String csnLink = h_.reportFileName + "/" + h_.reportFileName + "-summary" + h_.reportFileExt;
+
+            h_.writeText("    <FRAME SRC=\"" + tlfLink + "\" SCROLLING=\"no\" NAME=\"topleftframe\">");
+            h_.writeText("    <FRAME SRC=\"" + allDiffsLink + "\" SCROLLING=\"auto\" NAME=\"bottomleftframe\">");
+            h_.writeText("  </FRAMESET>");
+            h_.writeText("  <FRAME SRC=\"" + csnLink + "\" SCROLLING=\"auto\" NAME=\"rightframe\">");
+            h_.writeText("</FRAMESET>");
+            h_.writeText("<NOFRAMES>");
+            h_.writeText("<H2>");
+            h_.writeText("Frame Alert");
+            h_.writeText("</H2>\n");
+            h_.writeText("<P>");
+            h_.writeText("This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.");
+            h_.writeText("<BR>");
+            h_.writeText("Link to <A HREF=\"" + csnLink + "\" target=\"_top\">Non-frame version.</A>");
+            h_.writeText("</NOFRAMES>");
+            h_.writeText("</HTML>");
+            h_.reportFile.close();
+        } catch(IOException e) {
+            System.out.println("IO Error while attempting to create " + tln);
+            System.out.println("Error: " + e.getMessage());
+            System.exit(1);
+        }
+    }
+
+    /** Emit a top left frame with all the links to the index files. */
+    public void emitTopLeftFile(String tlf) {
+        try {
+            FileOutputStream fos = new FileOutputStream(tlf);
+            h_.reportFile = new PrintWriter(fos);
+            h_.writeStartHTMLHeader();
+            h_.writeHTMLTitle("Android Diffs Index");
+            h_.writeStyleSheetRef();
+            h_.writeText("</HEAD>");
+            h_.writeText("<BODY>");
+
+            h_.writeText("<table summary=\"Links to all index files\" BORDER=\"0\" WIDTH=\"100%\" cellspacing=\"0\" cellpadding=\"0\">");
+            h_.writeText("<TR>");
+            h_.writeText("  <th class=\"indexHeader\" nowrap>");
+            h_.writeText("  Select a Diffs Index:</th>");
+            h_.writeText("</TR>");
+            h_.writeText("<TR>");
+            h_.writeText("  <TD><FONT CLASS=\"indexText\" size=\"-1\"><A HREF=\"alldiffs_index_all" + h_.reportFileExt + "\" TARGET=\"bottomleftframe\">All Differences</A></FONT><br></TD>");
+            h_.writeText("</TR>");
+            h_.writeText("<TR>");
+            h_.writeText("  <TD NOWRAP><FONT CLASS=\"indexText\" size=\"-1\"><A HREF=\"packages_index_all" + h_.reportFileExt + "\" TARGET=\"bottomleftframe\">By Package</A></FONT><br></TD>");
+            h_.writeText("</TR>");
+            h_.writeText("<TR>");
+            h_.writeText("  <TD NOWRAP><FONT CLASS=\"indexText\" size=\"-1\"><A HREF=\"classes_index_all" + h_.reportFileExt + "\" TARGET=\"bottomleftframe\">By Class</A></FONT><br></TD>");
+            h_.writeText("</TR>");
+            h_.writeText("<TR>");
+            h_.writeText("  <TD NOWRAP><FONT CLASS=\"indexText\" size=\"-1\"><A HREF=\"constructors_index_all" + h_.reportFileExt + "\" TARGET=\"bottomleftframe\">By Constructor</A></FONT><br></TD>");
+            h_.writeText("</TR>");
+            h_.writeText("<TR>");
+            h_.writeText("  <TD NOWRAP><FONT CLASS=\"indexText\" size=\"-1\"><A HREF=\"methods_index_all" + h_.reportFileExt + "\" TARGET=\"bottomleftframe\">By Method</A></FONT><br></TD>");
+            h_.writeText("</TR>");
+            h_.writeText("<TR>");
+            h_.writeText("  <TD NOWRAP><FONT CLASS=\"indexText\" size=\"-1\"><A HREF=\"fields_index_all" + h_.reportFileExt + "\" TARGET=\"bottomleftframe\">By Field</A></FONT><br></TD>");
+            h_.writeText("</TR>");
+            h_.writeText("</TABLE>");
+
+            h_.writeHTMLFooter();
+            h_.reportFile.close();
+        } catch(IOException e) {
+            System.out.println("IO Error while attempting to create " + tlf);
+            System.out.println("Error: " + e.getMessage());
+            System.exit(1);
+        }
+    }
+
+    /** Emit the help file. */
+    public void emitHelp(String fullReportFileName, APIDiff apiDiff) {
+        String helpFileName = fullReportFileName + JDiff.DIR_SEP + "jdiff_help" + h_.reportFileExt;
+        try {
+            FileOutputStream fos = new FileOutputStream(helpFileName);
+            h_.reportFile = new PrintWriter(fos);
+            h_.writeStartHTMLHeader();
+            h_.writeHTMLTitle("JDiff Help");
+            h_.writeStyleSheetRef();
+            h_.writeText("</HEAD>");
+            h_.writeText("<BODY>");
+            // Write a customized navigation bar for the help page
+            h_.writeText("<!-- Start of nav bar -->");
+            h_.writeText("<TABLE summary=\"Navigation bar\" BORDER=\"0\" WIDTH=\"100%\" CELLPADDING=\"1\" CELLSPACING=\"0\">");
+            h_.writeText("<TR>");
+            h_.writeText("<TD COLSPAN=2 BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\">");
+            h_.writeText("  <TABLE summary=\"Navigation bar\" BORDER=\"0\" CELLPADDING=\"0\" CELLSPACING=\"3\">");
+            h_.writeText("    <TR ALIGN=\"center\" VALIGN=\"top\">");
+            // Always have a link to the Javadoc files
+            h_.writeText("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + h_.newDocPrefix + "index.html\" target=\"_top\"><FONT CLASS=\"NavBarFont1\"><B><tt>" + apiDiff.newAPIName_ + "</tt></B></FONT></A>&nbsp;</TD>");
+            h_.writeText("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + h_.reportFileName + "-summary" + h_.reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Overview</B></FONT></A>&nbsp;</TD>");
+            h_.writeText("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> &nbsp;<FONT CLASS=\"NavBarFont1\">Package</FONT>&nbsp;</TD>");
+            h_.writeText("      <TD BGCOLOR=\"#FFFFFF\" CLASS=\"NavBarCell1\"> &nbsp;<FONT CLASS=\"NavBarFont1\">Class</FONT>&nbsp;</TD>");
+            if (!Diff.noDocDiffs) {
+                h_.writeText("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + Diff.diffFileName + "index" + h_.reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Text Changes</B></FONT></A>&nbsp;</TD>");
+            }
+            if (h_.doStats) {
+                h_.writeText("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"jdiff_statistics" + h_.reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Statistics</B></FONT></A>&nbsp;</TD>");
+            }
+            h_.writeText("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1Rev\"> &nbsp;<FONT CLASS=\"NavBarFont1Rev\"><B>Help</B></FONT>&nbsp;</TD>");
+            h_.writeText("    </TR>");
+            h_.writeText("  </TABLE>");
+            h_.writeText("</TD>");
+
+            // The right hand side title
+            h_.writeText("<TD ALIGN=\"right\" VALIGN=\"top\" ROWSPAN=3><EM><b>Generated by<br><a href=\"" + JDiff.jDiffLocation + "\" class=\"staysblack\" target=\"_top\">JDiff</a></b></EM></TD>");
+            h_.writeText("</TR>");
+            
+            // Links for frames and no frames
+            h_.writeText("<TR>");
+            h_.writeText("  <TD BGCOLOR=\"" + h_.bgcolor + "\" CLASS=\"NavBarCell2\"><FONT SIZE=\"-2\"></FONT>");
+            h_.writeText("</TD>");
+            h_.writeText("  <TD BGCOLOR=\"" + h_.bgcolor + "\" CLASS=\"NavBarCell2\"><FONT SIZE=\"-2\">");
+            h_.writeText("  <A HREF=\"" + "../" + h_.reportFileName + h_.reportFileExt + "\" TARGET=\"_top\"><B>FRAMES</B></A>  &nbsp;");
+            h_.writeText("  &nbsp;<A HREF=\"jdiff_help" + h_.reportFileExt + "\" TARGET=\"_top\"><B>NO FRAMES</B></A></FONT></TD>");
+            h_.writeText("</TR>");
+            
+            h_.writeText("</TABLE>");
+            h_.writeText("<HR>");
+            h_.writeText ("<!-- End of nav bar -->");
+
+            h_.writeText("<center>");        
+            h_.writeText("<H1>JDiff Documentation</H1>");
+            h_.writeText("</center>");        
+
+            h_.writeText("<BLOCKQUOTE>");
+            h_.writeText("JDiff is a <a href=\"http://java.sun.com/j2se/javadoc/\" target=\"_top\">Javadoc</a> doclet which generates a report of the API differences between two versions of a product. It does not report changes in Javadoc comments, or changes in what a class or method does. ");
+            h_.writeText("This help page describes the different parts of the output from JDiff.");
+            h_.writeText("</BLOCKQUOTE>");
+
+            h_.writeText("<BLOCKQUOTE>");
+            h_.writeText(" See the reference page in the <a href=\"" + JDiff.jDiffLocation + "\">source for JDiff</a> for information about how to generate a report like this one.");
+            h_.writeText("</BLOCKQUOTE>");
+
+            h_.writeText("<BLOCKQUOTE>");
+            h_.writeText("The indexes shown in the top-left frame help show each type of change in more detail. The index \"All Differences\" contains all the differences between the APIs, in alphabetical order. ");
+            h_.writeText("These indexes all use the same format:");
+            h_.writeText("<ul>");
+            h_.writeText("<li>Removed packages, classes, constructors, methods and fields are <strike>struck through</strike>.</li>");
+            h_.writeText("<li>Added packages, classes, constructors, methods and fields appear in <b>bold</b>.</li>");
+            h_.writeText("<li>Changed packages, classes, constructors, methods and fields appear in normal text.</li>");
+            h_.writeText("</ul>");
+            h_.writeText("</BLOCKQUOTE>");
+
+            h_.writeText("<BLOCKQUOTE>");
+            h_.writeText("You can always tell when you are reading a JDiff page, rather than a Javadoc page, by the color of the index bar and the color of the background. ");
+            h_.writeText("Links which take you to a Javadoc page are always in a <tt>typewriter</tt> font. ");
+            h_.writeText("Just like Javadoc, all interface names are in <i>italic</i>, and class names are not italicized. Where there are multiple entries in an index with the same name, the heading for them is also in italics, but is not a link.");
+            h_.writeText("</BLOCKQUOTE>");
+
+            h_.writeText("<BLOCKQUOTE>");
+            h_.writeText("<H3><b><tt>Javadoc</tt></b></H3>");
+            h_.writeText("This is a link to the <a href=\"" + h_.newDocPrefix + "index.html\" target=\"_top\">top-level</a> Javadoc page for the new version of the product.");
+            h_.writeText("</BLOCKQUOTE>");
+            
+            h_.writeText("<BLOCKQUOTE>");
+            h_.writeText("<H3>Overview</H3>");        
+            h_.writeText("The <a href=\"" + h_.reportFileName + "-summary" + 
+                      h_.reportFileExt + "\">overview</a> is the top-level summary of what was removed, added and changed between versions.");        
+            h_.writeText("</BLOCKQUOTE>");
+            
+            h_.writeText("<BLOCKQUOTE>");
+            h_.writeText("<H3>Package</H3>");        
+            h_.writeText("This is a link to the package containing the current changed class or interface.");        
+            h_.writeText("</BLOCKQUOTE>");
+            
+            h_.writeText("<BLOCKQUOTE>");
+            h_.writeText("<H3>Class</H3>");        
+            h_.writeText("This is highlighted when you are looking at the changed class or interface.");        
+            h_.writeText("</BLOCKQUOTE>");
+            
+            h_.writeText("<BLOCKQUOTE>");
+            h_.writeText("<H3>Text Changes</H3>");        
+            h_.writeText("This is a link to the top-level index of all documentation changes for the current package or class. ");        
+            h_.writeText("If it is not present, then there are no documentation changes for the current package or class. ");        
+            h_.writeText("This link can be removed entirely by not using the <code>-docchanges</code> option.");        
+            h_.writeText("</BLOCKQUOTE>");
+            
+            h_.writeText("<BLOCKQUOTE>");
+            h_.writeText("<H3>Statistics</H3>");        
+            h_.writeText("This is a link to a page which shows statistics about the changes between the two APIs.");        
+            h_.writeText("This link can be removed entirely by not using the <code>-stats</code> option.");        
+            h_.writeText("</BLOCKQUOTE>");
+            
+            h_.writeText("<BLOCKQUOTE>");
+            h_.writeText("<H3>Help</H3>");        
+            h_.writeText("A link to this Help page for JDiff.");
+            h_.writeText("</BLOCKQUOTE>");
+
+            h_.writeText("<BLOCKQUOTE>");
+            h_.writeText("<H3>Prev/Next</H3>");        
+            h_.writeText("These links take you to the previous  and next changed package or class.");        
+            h_.writeText("</BLOCKQUOTE>");
+            
+            h_.writeText("<BLOCKQUOTE>");
+            h_.writeText("<H3>Frames/No Frames</H3>");        
+            h_.writeText("These links show and hide the HTML frames. All pages are available with or without frames.");        
+            h_.writeText("</BLOCKQUOTE>");
+            
+            h_.writeText("<BLOCKQUOTE>");
+            h_.writeText("<H2>Complex Changes</H2>");
+            h_.writeText("There are some complex changes which can occur between versions, for example, when two or more methods with the same name change simultaneously, or when a method or field is moved into or from a superclass. ");
+            h_.writeText("In these cases, the change will be seen as a removal and an addition, rather than as a change. Unexpected removals or additions are often part of one of these type of changes. ");
+            h_.writeText("</BLOCKQUOTE>");
+            
+            h_.writeHTMLFooter();
+            h_.reportFile.close();
+        } catch(IOException e) {
+            System.out.println("IO Error while attempting to create " + helpFileName);
+            System.out.println("Error: " + e.getMessage());
+            System.exit(1);
+        }
+    }
+
+    /** Emit the CSS external stylesheet file. */
+    public void emitStylesheet() {
+        String stylesheetFileName = "stylesheet-jdiff.css";
+        if (h_.outputDir != null)
+            stylesheetFileName = h_.outputDir + JDiff.DIR_SEP + stylesheetFileName;
+        try {
+            FileOutputStream fos = new FileOutputStream(stylesheetFileName);
+            h_.reportFile = new PrintWriter(fos);
+            h_.writeText();
+            h_.writeText("/* (" + JDiff.jDiffLocation + ") */");
+            //h_.writeText("/* on " + new Date() + " */");
+            h_.writeText();
+            //h_.writeText("/* Define colors, fonts and other style attributes here to override the defaults  */");
+            //h_.writeText();
+            //h_.writeText("/* Page background color */");
+            //h_.writeText("body { background-color: " + h_.bgcolor + "; font-family: arial; }");
+            //First argument after backgroun: is for older Netscape browsers
+            //For more information, see http://css.nu/pointers/bugs.html and 
+            //http://www.richinstyle.com/bugs/netscape4.html
+            //h_.writeText("body { background: #CCFFFF url(background.gif); font-family: arial; }");
+            //h_.writeText();
+            //h_.writeText("/* Table colors */");
+            //h_.writeText(".TableHeadingColor     { background: #CCCCFF } /* Dark mauve */");
+            //h_.writeText(".TableSubHeadingColor  { background: #EEEEFF } /* Light mauve */");
+            //h_.writeText(".TableRowColor         { background: #FFFFFF } /* White */");
+            //h_.writeText();
+            //h_.writeText("/* Font used in left-hand frame lists */");
+            //h_.writeText(".FrameTitleFont   { font-size: normal; font-family: normal }");
+            //h_.writeText(".FrameHeadingFont { font-size: normal; font-family: normal }");
+            //h_.writeText(".FrameItemFont    { font-size: normal; font-family: normal }");
+            //h_.writeText();
+            //h_.writeText("/* Example of smaller, sans-serif font in frames */");
+            //h_.writeText("/* .FrameItemFont  { font-size: 10pt; font-family: Helvetica, Arial, sans-serif } */");
+            //h_.writeText();
+            //h_.writeText("/* Navigation bar fonts and colors */");
+            //h_.writeText(".NavBarCell1    { background-color:#FFFFCC;} /* Changed to yellowish to make difference from Javadoc clear */");
+            //h_.writeText(".NavBarCell1Rev { background-color:#00008B;}/* Dark Blue */");
+            //h_.writeText(".NavBarFont1    { font-family: Arial, Helvetica, sans-serif; color:#000000;}");
+            //h_.writeText(".NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;}");
+            //h_.writeText();
+            //h_.writeText(".NavBarCell2    { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;}");
+            //h_.writeText(".NavBarCell3    { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;}");
+            //h_.writeText();
+            h_.writeText("/* ");
+            h_.writeText(" Links which become blue when hovered upon and show that they have been ");
+            h_.writeText(" visited. ");
+            h_.writeText("*/");
+	    h_.writeText(".hiddenlink {text-decoration:none;}");
+            h_.writeText("a.hiddenlink:link      {color: black; text-decoration: none}");
+            h_.writeText("a.hiddenlink:visited   {color: purple; text-decoration: none}");
+            h_.writeText("a.hiddenlink:hover     {color: blue; text-decoration: underline;}");
+            h_.writeText();
+            h_.writeText("/* ");
+            h_.writeText(" Links which become blue when hovered upon but do not show that they have ");
+            h_.writeText(" been visited. ");
+            h_.writeText("*/");
+            h_.writeText("a.staysblack:link     {color: black; text-decoration: none}");
+            h_.writeText("a.staysblack:visited  {color: black; text-decoration: none}");
+            h_.writeText("a.staysblack:hover    {color: blue; text-decoration: underline;}");
+            h_.writeText("");
+            h_.writeText("div.and-diff-id {border: 1px solid #eee;position:relative;float:right;clear:both;padding:0px;}");
+            h_.writeText("table.diffspectable {border:1px;padding:0px;margin:0px;}");
+            h_.writeText(".diffspectable tr {border:0px;padding:0px;}");
+            h_.writeText(".diffspectable td  {background-color:eee;border:0px;font-size:90%;font-weight:normal;padding:0px;padding-left:1px;padding-right:1px;text-align:center;color:777;}");
+            h_.writeText("td.diffvalueold {color:orange;background-color:white;border:0px;font-size:80%;font-style:normal;text-align:left;padding:0px;padding-left:1px;padding-right:1px;line-height:.95em;}");
+            h_.writeText("td.diffvaluenew {color:green;background-color:white;border:0px;font-size:80%;font-weight:normal;text-align:left;padding:0px;padding-left:1px;padding-right:1px;line-height:.95em;}");
+            h_.writeText("td.diffvalue {color:444;background-color:white;border:0px;font-size:80%;font-weight:normal;text-align:left;padding:0px;padding-left:1px;padding-right:1px;line-height:.95em;}");
+            h_.writeText("td.diffspec {background-color:white;border:0px;font-size:80%;font-weight:normal;padding:1px;color:444;text-align:right;padding-right:.5em;line-height:.95em;}");
+            h_.writeText("tt {font-size:11pt;font-family:monospace;}");
+            h_.writeText("code {font-size:11pt;font-family:monospace;}");
+            h_.writeText(".indexHeader {font-size:11pt;line-height:.8em;}");
+            h_.writeText(".indexText {font-size:9pt;line-height:.8em;padding-left:1em;}");
+
+            h_.writeText(".pagecontenth1 {");
+            h_.writeText("  line-height: 130%;");
+            h_.writeText("  font-size: 170%;");
+            h_.writeText("  xmargin: 0 0 0 -10px;");
+            h_.writeText("  padding: .8em 0 0;");
+            h_.writeText("  border: none;");
+            h_.writeText("  background: none;");
+            h_.writeText("}");
+            h_.writeText("");
+            h_.writeText(".pagecontenth2 {");
+            h_.writeText("  font-size: 130%;");
+            h_.writeText("  font-weight: bold;");
+            h_.writeText("  margin: 2em 0 0 -10px; ");
+            h_.writeText("  padding: 1px 3px;");
+            h_.writeText("  position: relative;");
+            h_.writeText("  border-top: 1px solid #3366CC;");
+            h_.writeText("  background-color: #e5ecf9;");
+            h_.writeText("}");
+            h_.reportFile.close();
+
+        } catch(IOException e) {
+            System.out.println("IO Error while attempting to create " + stylesheetFileName);
+            System.out.println("Error: " + e.getMessage());
+            System.exit(1);
+        }
+    }
+
+}
diff --git a/src/jdiff/HTMLIndexes.java b/src/jdiff/HTMLIndexes.java
new file mode 100755
index 0000000..d39e023
--- /dev/null
+++ b/src/jdiff/HTMLIndexes.java
@@ -0,0 +1,1097 @@
+package jdiff;
+
+import java.util.*;
+import java.io.*;
+
+/**
+ * Emit HTML indexes which appear in the bottom left frame in the report. 
+ * All indexes are links to JDiff-generated pages.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+public class HTMLIndexes {
+
+    /** Constructor. */
+    public HTMLIndexes(HTMLReportGenerator h) {
+        h_ = h;
+    }
+
+    /** The HTMLReportGenerator instance used to write HTML. */
+    private HTMLReportGenerator h_ = null;
+    
+    /** Emit all the bottom left frame index files. */
+    public void emitAllBottomLeftFiles(String packagesIndexName, 
+                                       String classesIndexName, 
+                                       String constructorsIndexName, 
+                                       String methodsIndexName,
+                                       String fieldsIndexName, 
+                                       String allDiffsIndexName, 
+                                       APIDiff apiDiff) {
+        
+        // indexType values: 0 = removals only, 1 = additions only, 
+        // 2 = changes only. 3 = all differences. Run all differences
+        // first for all program element types so we know whether there
+        // are any removals etc for the allDiffs index.
+        emitBottomLeftFile(packagesIndexName, apiDiff, 3, "Package");
+        emitBottomLeftFile(classesIndexName, apiDiff, 3, "Class");
+        emitBottomLeftFile(constructorsIndexName, apiDiff, 3, "Constructor");
+        emitBottomLeftFile(methodsIndexName, apiDiff, 3, "Method");
+        emitBottomLeftFile(fieldsIndexName, apiDiff, 3, "Field");
+        // The allindex must be done last, since it uses the results from 
+        // the previous ones
+        emitBottomLeftFile(allDiffsIndexName, apiDiff, 3, "All");
+        // Now generate the other indexes
+        for (int indexType = 0; indexType < 3; indexType++) {
+            emitBottomLeftFile(packagesIndexName, apiDiff, indexType, "Package");
+            emitBottomLeftFile(classesIndexName, apiDiff, indexType, "Class");
+            emitBottomLeftFile(constructorsIndexName, apiDiff, indexType, "Constructor");
+            emitBottomLeftFile(methodsIndexName, apiDiff, indexType, "Method");
+            emitBottomLeftFile(fieldsIndexName, apiDiff, indexType, "Field");
+            emitBottomLeftFile(allDiffsIndexName, apiDiff, indexType, "All");
+        }
+        if (missingSincesFile != null)
+            missingSincesFile.close();
+    }
+
+    /** 
+     * Emit a single bottom left frame with the given kind of differences for 
+     * the given program element type in an alphabetical index. 
+     *
+     * @param indexBaseName The base name of the index file.
+     * @param apiDiff The root element containing all the API differences.
+     * @param indexType 0 = removals only, 1 = additions only,
+     *                  2 = changes only, 3 = all differences, 
+     * @param programElementType "Package", "Class", "Constructor",
+     *                           "Method", "Field" or "All".  
+     */
+    public void emitBottomLeftFile(String indexBaseName, 
+                                   APIDiff apiDiff, int indexType, 
+                                   String programElementType) {
+        String filename = indexBaseName;
+        try {
+            String title = "Indexes"; 
+            if (indexType == 0) {
+                filename += "_removals" + h_.reportFileExt;
+                title = programElementType + " Removals Index";
+            } else if (indexType == 1) {
+                filename += "_additions" + h_.reportFileExt;
+                title = programElementType + " Additions Index";
+            } else if (indexType == 2) {
+                filename += "_changes" + h_.reportFileExt;
+                title = programElementType + " Changes Index";
+            } else if (indexType == 3) {
+                filename += "_all" + h_.reportFileExt;
+                title = programElementType + " Differences Index";
+            }
+                
+            FileOutputStream fos = new FileOutputStream(filename);
+            h_.reportFile = new PrintWriter(fos);
+            h_.writeStartHTMLHeader();
+            h_.writeHTMLTitle(title);
+            h_.writeStyleSheetRef();
+            h_.writeText("</HEAD>");
+            h_.writeText("<BODY>");
+            
+            if (programElementType.compareTo("Package") == 0) {
+                emitPackagesIndex(apiDiff, indexType);
+            } else if (programElementType.compareTo("Class") == 0) {
+                emitClassesIndex(apiDiff, indexType);
+            } else if (programElementType.compareTo("Constructor") == 0) {
+                emitConstructorsIndex(apiDiff, indexType);
+            } else if (programElementType.compareTo("Method") == 0) {
+                emitMethodsIndex(apiDiff, indexType);
+            } else if (programElementType.compareTo("Field") == 0) {
+                emitFieldsIndex(apiDiff, indexType);
+            } else if (programElementType.compareTo("All") == 0) {
+                emitAllDiffsIndex(apiDiff, indexType);
+            } else{
+                System.out.println("Error: unknown program element type.");
+                System.exit(3);
+            }
+            
+            h_.writeHTMLFooter();
+            h_.reportFile.close();
+        } catch(IOException e) {
+            System.out.println("IO Error while attempting to create " + filename);
+            System.out.println("Error: " + e.getMessage());
+            System.exit(1);
+        }
+    }
+
+    /** 
+     * Generate a small header of letters which link to each section, but
+     * do not emit a linked letter for the current section. Finish the list off
+     * with a link to the top of the index.
+     * Caching the results of this function would save about 10s with large APIs.
+     */
+    private void generateLetterIndex(List list, char currChar, boolean larger) {
+        if (larger)
+            return; // Currently not using the larger functionality
+        int size = -2;
+	if (larger)
+            size = -1;
+        Iterator iter = null;
+        if (isAllNames)
+            iter = allNames.iterator();
+        else
+            iter = list.iterator();
+        char oldsw = '\0';
+        while (iter.hasNext()) {
+            Index entry = (Index)(iter.next());
+            char sw = entry.name_.charAt(0);
+            char swu = Character.toUpperCase(sw);
+            if (swu != Character.toUpperCase(oldsw)) {
+                // Don't emit a reference to the current letter
+                if (Character.toUpperCase(sw) != Character.toUpperCase(currChar)) {
+                    if (swu == '_') {
+                        h_.writeText("<a href=\"#" + swu + "\"><font size=\"" + size + "\">" + "underscore" + "</font></a> ");
+                    } else {
+                        h_.writeText("<a href=\"#" + swu + "\"><font size=\"" + size + "\">" + swu + "</font></a> ");
+                    }
+                }
+                oldsw = sw;
+            }
+        }
+        h_.writeText(" <a href=\"#topheader\"><font size=\"" + size + "\">TOP</font></a>");
+        h_.writeText("<p><div style=\"line-height:1.5em;color:black\">");
+    }
+
+    /** 
+     * Emit a header for an index, including suitable links for removed, 
+     * added and changes sub-indexes. 
+     */
+    private void emitIndexHeader(String indexName, int indexType,
+                                 boolean hasRemovals, 
+                                 boolean hasAdditions, boolean hasChanges) {
+        String linkIndexName = indexName.toLowerCase();
+        boolean isAllDiffs = false;
+        if (indexName.compareTo("All Differences") == 0) {
+            linkIndexName = "alldiffs";
+            isAllDiffs = true;
+        }
+        h_.writeText("<a NAME=\"topheader\"></a>"); // Named anchor
+        h_.writeText("<table summary=\"Index for " +  indexName + "\" width=\"100%\" class=\"index\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">");
+        h_.writeText("  <tr>");
+        h_.writeText("  <th class=\"indexHeader\">");
+        h_.writeText("    Filter the Index:");
+        h_.writeText("  </th>");
+        h_.writeText("  </tr>");
+        h_.writeText("  <tr>");
+        h_.writeText("  <td class=\"indexText\" style=\"line-height:1.5em;padding-left:2em;\">");
+//        h_.writeText("  <div style=\"line-height:1.25em;padding-left:1em;>\">");
+//        h_.writeText("  <FONT SIZE=\"-1\">");
+        // The index name is also a hidden link to the *index_all page
+        if (indexType == 3) {
+             h_.writeText("<b>" + indexName + "</b>"); }
+        else if (isAllDiffs) {
+            h_.writeText("<a href=\"" + linkIndexName + "_index_all" + h_.reportFileExt + "\" class=\"hiddenlink\">" + indexName + "</a>");
+        }
+        else {
+            h_.writeText("<a href=\"" + linkIndexName + "_index_all" + h_.reportFileExt + "\" class=\"staysblack\">All " + indexName + "</a>");
+        }
+//        h_.writeText("  </FONT>");
+
+        h_.writeText("  <br>");
+//        h_.writeText("  <FONT SIZE=\"-1\">");
+        if (hasRemovals) {
+          if (indexType == 0) {
+            h_.writeText("<b>Removals</b>");
+          } else {
+            h_.writeText("<A HREF=\"" + linkIndexName + "_index_removals" + h_.reportFileExt + "\" class=\"hiddenlink\">Removals</A>");
+          }
+        } else {
+            h_.writeText("<font color=\"#999999\">Removals</font>");
+        }
+//        h_.writeText("  </FONT>");
+
+        h_.writeText("  <br>");
+//      h_.writeText("  <FONT SIZE=\"-1\">");
+        if (hasAdditions) {
+          if (indexType == 1) {
+            h_.writeText("<b>Additions</b>");
+          } else {
+            h_.writeText("<A HREF=\"" + linkIndexName + "_index_additions" + h_.reportFileExt + "\"class=\"hiddenlink\">Additions</A>");
+          }
+        } else {
+            h_.writeText("<font color=\"#999999\">Additions</font>");
+        }
+//        h_.writeText("  </FONT>");
+
+        h_.writeText("  <br>");
+//         h_.writeText("  <FONT SIZE=\"-1\">");
+        if (hasChanges) {
+          if (indexType == 2) {
+            h_.writeText("<b>Changes</b>");
+          } else {
+            h_.writeText("<A HREF=\"" + linkIndexName + "_index_changes" + h_.reportFileExt + "\"class=\"hiddenlink\">Changes</A>");
+          }
+        } else {
+            h_.writeText("<font color=\"#999999\">Changes</font>");
+        }
+//        h_.writeText("  </FONT>");
+//        h_.writeText("  </div>");
+        h_.writeText("  </td>");
+        h_.writeText("  </tr>");
+        h_.writeText("</table>");
+        h_.writeText("<font size=\"-2\"><strong>Bold</strong>&nbsp;indicates&nbsp;New;&nbsp;<strike>Strike</strike>&nbsp;indicates&nbsp;deleted</font>");
+        h_.writeText("  </br>");
+
+    }
+
+    /** Emit the index of packages, which appears in the bottom left frame. */
+    public void emitPackagesIndex(APIDiff apiDiff, int indexType) {
+        // Add all the names of packages to a new list, to be sorted later
+        packageNames = new ArrayList(); // Index[]
+        boolean hasRemovals = false;
+        if (apiDiff.packagesRemoved.size() != 0)
+            hasRemovals = true;
+        boolean hasAdditions = false;
+        if (apiDiff.packagesAdded.size() != 0)
+            hasAdditions = true;
+        boolean hasChanges = false;
+        if (apiDiff.packagesChanged.size() != 0)
+            hasChanges = true;
+        recordDiffs(hasRemovals, hasAdditions, hasChanges);
+        Iterator iter = apiDiff.packagesRemoved.iterator();
+        while ((indexType == 3 || indexType == 0) && iter.hasNext()) {
+            PackageAPI pkg = (PackageAPI)(iter.next());
+            packageNames.add(new Index(pkg.name_, 0));
+        }
+        iter = apiDiff.packagesAdded.iterator();
+        while ((indexType == 3 || indexType == 1) && iter.hasNext()) {
+            PackageAPI pkg = (PackageAPI)(iter.next());
+            packageNames.add(new Index(pkg.name_, 1));
+        }
+        iter = apiDiff.packagesChanged.iterator();
+        while ((indexType == 3 || indexType == 2) && iter.hasNext()) {
+            PackageDiff pkg = (PackageDiff)(iter.next());
+            packageNames.add(new Index(pkg.name_, 2));
+        }
+        Collections.sort(packageNames);
+
+        // No letter index needed for packages
+
+        // Now emit all the package names and links to their respective files
+        emitIndexHeader("Packages", indexType, hasRemovals, hasAdditions, hasChanges);
+
+        // Extra line because no index is emitted
+        h_.writeText("<br>");
+
+        // Package names are unique, so no need to check for duplicates.
+        iter = packageNames.iterator();
+        char oldsw = '\0';
+        while (iter.hasNext()) {
+            Index pkg = (Index)(iter.next());
+            oldsw = emitPackageIndexEntry(pkg, oldsw);
+        }
+    }
+
+    /** 
+     * Emit an index entry for a package. 
+     * Package names are unique, so no need to check for duplicates.
+     */
+    public char emitPackageIndexEntry(Index pkg, char oldsw) {
+        char res = oldsw;
+        // See if we are in a new section of the alphabet
+        char sw = pkg.name_.charAt(0);
+        if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) {
+            // No need to emit section letters for packages
+            res = sw;
+            // Add the named anchor for this new letter
+            h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>");
+        }
+        // Package names are unique, so no need to check for duplicates.
+        if (pkg.changeType_ == 0) {
+            h_.writeText("<A HREF=\"" + h_.reportFileName + "-summary" + h_.reportFileExt + "#" + pkg.name_  + "\" class=\"hiddenlink\" target=\"rightframe\"><strike>" + pkg.name_ + "</strike></A><br>");
+        } else if (pkg.changeType_ == 1) {
+            h_.writeText("<A HREF=\"" + h_.reportFileName + "-summary" + h_.reportFileExt + "#" + pkg.name_  + "\" class=\"hiddenlink\" target=\"rightframe\"><b>" + pkg.name_ + "</b></A><br>");
+        } else if (pkg.changeType_ == 2) {
+            h_.writeText("<A HREF=\"pkg_" + pkg.name_ + h_.reportFileExt + "\" class=\"hiddenlink\" target=\"rightframe\">" + pkg.name_ + "</A><br>");
+        }
+        return res;
+    }
+
+    /** 
+     * Emit all the entries and links for the given iterator
+     * to their respective files. 
+     */
+    public void emitIndexEntries(Iterator iter) {
+        char oldsw = '\0';
+        int multipleMarker = 0;
+        Index currIndex = null; // The entry which is emitted
+        while (iter.hasNext()) {
+            // The next entry after the current one
+            Index nextIndex = (Index)(iter.next()); 
+            if (currIndex == null) {
+                currIndex = nextIndex; // Prime the pump
+            } else {
+                if (nextIndex.name_.compareTo(currIndex.name_) == 0) {
+                    // It's a duplicate index, so emit the name and then
+                    // the indented entries
+                    if (multipleMarker == 0)
+                        multipleMarker = 1; // Start of a duplicate index
+                    else if (multipleMarker == 1)
+                        multipleMarker = 2; // Inside a duplicate index
+                    oldsw = emitIndexEntry(currIndex, oldsw, multipleMarker);
+                } else {
+                    if (multipleMarker == 1)
+                        multipleMarker = 2; // Inside a duplicate index
+                    oldsw = emitIndexEntry(currIndex, oldsw, multipleMarker);
+                    multipleMarker = 0; // Not in a duplicate index any more
+                }
+                currIndex = nextIndex;
+            }
+        }
+        // Emit the last entry left in currIndex
+        if (multipleMarker == 1)
+            multipleMarker = 2; // Inside a duplicate index
+        if (currIndex != null)
+            oldsw = emitIndexEntry(currIndex, oldsw, multipleMarker);
+    }
+    
+    /** 
+     * Whether to log all missing @since tags to a file or not. 
+     * If false, just warn the user.
+     */
+    public static boolean logMissingSinces = true;
+
+    /** The file used to output details of missing @since tags. */
+    public static PrintWriter missingSincesFile = null;
+
+    /** 
+     * Emit elements in the given iterator which were added and 
+     * missing @since tags. 
+     */
+    public void emitMissingSinces(Iterator iter) {
+//        if (!logMissingSinces)
+//            return;
+        if (missingSincesFile == null) {
+            String sinceFileName = h_.outputDir + JDiff.DIR_SEP + "missingSinces.txt";
+            try {
+                FileOutputStream fos = new FileOutputStream(sinceFileName);
+                missingSincesFile = new PrintWriter(fos);
+            } catch (IOException e) {
+                System.out.println("IO Error while attempting to create " + sinceFileName);
+                System.out.println("Error: " + e.getMessage());
+                System.exit(1);
+            }
+        }
+        while (iter.hasNext()) {
+            Index currIndex = (Index)(iter.next()); 
+            // Only display information about added elements
+            if (currIndex.changeType_ != 1) 
+                continue;
+            String programElementType = currIndex.ename_;
+            String details = null;
+            if (programElementType.compareTo("class") == 0) {
+                details = currIndex.pkgName_ + "." + currIndex.name_;
+                if (currIndex.isInterface_)
+                    details = details + " Interface";
+                else
+                    details = details + " Class";
+            } else if (programElementType.compareTo("constructor") == 0) {
+                details = currIndex.pkgName_ + "." + currIndex.name_ + " Constructor (" + currIndex.type_ + ")";
+            } else if (programElementType.compareTo("method") == 0) {
+                details = currIndex.pkgName_ + "." + currIndex.className_ + " " + "Method " + currIndex.name_ + "(" + currIndex.type_ + ")";
+            } else if (programElementType.compareTo("field") == 0) {
+                details = currIndex.pkgName_ + "." + currIndex.className_ + " " + "Field " + currIndex.name_;
+            } else {
+                System.out.println("Error: unknown program element type");
+                System.exit(3);
+            }
+            if (currIndex.doc_ == null) {
+                if (logMissingSinces)
+                    missingSincesFile.println("NO DOC BLOCK: " + details);
+                else
+                    System.out.println("Warning: the doc block for the new element: " + details + " is missing, so there is no @since tag");
+            } else if (currIndex.doc_.indexOf("@since") != -1) {
+                if (logMissingSinces)
+                    missingSincesFile.println("OK: " + details);
+            } else {
+                if (logMissingSinces)
+                    missingSincesFile.println("MISSING @SINCE TAG: " + details);
+                else
+                    System.out.println("Warning: the doc block for the new element: " + details + " is missing an @since tag");
+            }
+        }
+    }
+    
+    /** 
+     * Emit a single entry and the link to its file.
+     *
+     * @param programElementType "Class", "Constructor",
+     *                           "Method", or "Field".
+     */
+    public char emitIndexEntry(Index currIndex, char oldsw, int multipleMarker) {
+        String programElementType = currIndex.ename_;
+        if (programElementType.compareTo("class") == 0) {
+            return emitClassIndexEntry(currIndex, oldsw, multipleMarker);
+        } else if (programElementType.compareTo("constructor") == 0) {
+            return emitCtorIndexEntry(currIndex, oldsw, multipleMarker);
+        } else if (programElementType.compareTo("method") == 0) {
+            return emitMethodIndexEntry(currIndex, oldsw, multipleMarker);
+        } else if (programElementType.compareTo("field") == 0) {
+            return emitFieldIndexEntry(currIndex, oldsw, multipleMarker);
+        } else {
+            System.out.println("Error: unknown program element type");
+            System.exit(3);
+        }
+        return '\0';
+    }
+
+    /** Emit the index of classes, which appears in the bottom left frame. */
+    public void emitClassesIndex(APIDiff apiDiff, int indexType) {
+        // Add all the names of classes to a new list, to be sorted later
+        classNames = new ArrayList(); // Index[]
+        boolean hasRemovals = false;
+        boolean hasAdditions = false;
+        boolean hasChanges = false;
+        Iterator iter = apiDiff.packagesChanged.iterator();
+        while (iter.hasNext()) {
+            PackageDiff pkgDiff = (PackageDiff)(iter.next());
+            if (pkgDiff.classesRemoved.size() != 0)
+                hasRemovals = true;
+            if (pkgDiff.classesAdded.size() != 0)
+                hasAdditions = true;
+            if (pkgDiff.classesChanged.size() != 0)
+                hasChanges = true;
+            recordDiffs(hasRemovals, hasAdditions, hasChanges);
+            String pkgName = pkgDiff.name_;
+            Iterator iterClass = pkgDiff.classesRemoved.iterator();
+            while ((indexType == 3 || indexType == 0) && iterClass.hasNext()) {
+                ClassAPI cls = (ClassAPI)(iterClass.next());
+                classNames.add(new Index(cls.name_, 0, pkgName, cls.isInterface_));
+            }
+            iterClass = pkgDiff.classesAdded.iterator();
+            while ((indexType == 3 || indexType == 1) && iterClass.hasNext()) {
+                ClassAPI cls = (ClassAPI)(iterClass.next());
+                Index idx = new Index(cls.name_, 1, pkgName, cls.isInterface_);
+                idx.doc_ = cls.doc_; // Used for checking @since
+                classNames.add(idx);
+            }
+            iterClass = pkgDiff.classesChanged.iterator();
+            while ((indexType == 3 || indexType == 2) && iterClass.hasNext()) {
+                ClassDiff cls = (ClassDiff)(iterClass.next());
+                classNames.add(new Index(cls.name_, 2, pkgName, cls.isInterface_));
+            }
+        }
+        Collections.sort(classNames);
+        emitIndexHeader("Classes", indexType, hasRemovals, hasAdditions, hasChanges);
+        emitIndexEntries(classNames.iterator());
+        if (indexType == 1)
+            emitMissingSinces(classNames.iterator());
+    }
+
+    /** Emit an index entry for a class. */
+    public char emitClassIndexEntry(Index cls, char oldsw, 
+                                    int multipleMarker) {
+        char res = oldsw;
+        String className = cls.pkgName_ + "." + cls.name_;
+        String classRef = cls.pkgName_ + "." + cls.name_;
+        boolean isInterface = cls.isInterface_;
+        // See if we are in a new section of the alphabet
+        char sw = cls.name_.charAt(0);
+        if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) {
+            res = sw;
+            // Add the named anchor for this new letter
+            h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>");
+            if (sw == '_')
+                h_.writeText("<br><b>underscore</b>&nbsp;");
+            else
+                h_.writeText("<br><font size=\"+2\">" + Character.toUpperCase(sw) + "</font>&nbsp;");
+            generateLetterIndex(classNames, sw, false);
+        }
+        // Deal with displaying duplicate indexes
+        if (multipleMarker == 1) {
+            h_.writeText("<i>" + cls.name_ + "</i><br>");
+        }
+        if (multipleMarker != 0)
+            h_.indent(INDENT_SIZE);
+        if (cls.changeType_ == 0) {
+            // Emit a reference to the correct place for the class in the 
+            // JDiff page for the package
+            h_.writeText("<A HREF=\"pkg_" + cls.pkgName_ + h_.reportFileExt + 
+                         "#" + cls.name_ + "\" class=\"hiddenlink\" target=\"rightframe\"><strike>" + cls.name_ + "</strike></A><br>");
+        } else if (cls.changeType_ == 1) {
+            String cn = cls.name_;
+            if (multipleMarker != 0)
+                cn = cls.pkgName_;
+            if (isInterface)
+                h_.writeText("<A HREF=\"pkg_" + cls.pkgName_ + h_.reportFileExt + "#" + cls.name_ + "\" class=\"hiddenlink\" target=\"rightframe\"><b><i>" + cn + "</i></b></A><br>");
+            else
+                h_.writeText("<A HREF=\"pkg_" + cls.pkgName_ + h_.reportFileExt + "#" + cls.name_ + "\" class=\"hiddenlink\" target=\"rightframe\"><b>" + cn + "</b></A><br>");
+        } else if (cls.changeType_ == 2) {
+            String cn = cls.name_;
+            if (multipleMarker != 0)
+                cn = cls.pkgName_;
+            if (isInterface)
+                h_.writeText("<A HREF=\"" + classRef + h_.reportFileExt + "\" class=\"hiddenlink\" target=\"rightframe\"><i>" + cn + "</i></A><br>");
+            else
+                h_.writeText("<A HREF=\"" + classRef + h_.reportFileExt + "\" class=\"hiddenlink\" target=\"rightframe\">" + cn + "</A><br>");
+        }
+        return res;
+    }
+    
+    /** 
+     * Emit the index of all constructors, which appears in the bottom left 
+     * frame. 
+     */
+    public void emitConstructorsIndex(APIDiff apiDiff, int indexType) {
+        // Add all the names of constructors to a new list, to be sorted later
+        ctorNames = new ArrayList(); // Index[]
+        boolean hasRemovals = false;
+        boolean hasAdditions = false;
+        boolean hasChanges = false;
+        Iterator iter = apiDiff.packagesChanged.iterator();
+        while (iter.hasNext()) {
+            PackageDiff pkgDiff = (PackageDiff)(iter.next());
+            String pkgName = pkgDiff.name_;
+            Iterator iterClass = pkgDiff.classesChanged.iterator();
+            while (iterClass.hasNext()) {
+                ClassDiff classDiff = (ClassDiff)(iterClass.next());
+                if (classDiff.ctorsRemoved.size() != 0)
+                    hasRemovals = true;
+                if (classDiff.ctorsAdded.size() != 0)
+                    hasAdditions = true;
+                if (classDiff.ctorsChanged.size() != 0)
+                    hasChanges = true;
+                recordDiffs(hasRemovals, hasAdditions, hasChanges);
+                String className = classDiff.name_;
+                Iterator iterCtor = classDiff.ctorsRemoved.iterator();
+                while ((indexType == 3 || indexType == 0) && iterCtor.hasNext()) {
+                    ConstructorAPI ctor = (ConstructorAPI)(iterCtor.next());
+                    ctorNames.add(new Index(className, 0, pkgName, ctor.type_));
+                }
+                iterCtor = classDiff.ctorsAdded.iterator();
+                while ((indexType == 3 || indexType == 1) && iterCtor.hasNext()) {
+                    ConstructorAPI ctor = (ConstructorAPI)(iterCtor.next());
+                    Index idx = new Index(className, 1, pkgName, ctor.type_);
+                    idx.doc_ = ctor.doc_; // Used for checking @since
+                    ctorNames.add(idx);
+                }
+                iterCtor = classDiff.ctorsChanged.iterator();
+                while ((indexType == 3 || indexType == 2) && iterCtor.hasNext()) {
+                    MemberDiff ctor = (MemberDiff)(iterCtor.next());
+                    ctorNames.add(new Index(className, 2, pkgName, ctor.newType_));
+                }
+            }
+        }
+        Collections.sort(ctorNames);
+        emitIndexHeader("Constructors", indexType, hasRemovals, hasAdditions, hasChanges);
+        emitIndexEntries(ctorNames.iterator());
+        if (indexType == 1)
+            emitMissingSinces(ctorNames.iterator());
+    }
+
+    /** Emit an index entry for a constructor. */
+    public char emitCtorIndexEntry(Index ctor, char oldsw, int multipleMarker) {
+        char res = oldsw;
+        String className = ctor.pkgName_ + "." + ctor.name_;
+        String memberRef = ctor.pkgName_ + "." + ctor.name_;
+        String type = ctor.type_;
+        if (type.compareTo("void") == 0)
+            type = "";
+        String shownType = HTMLReportGenerator.simpleName(type);
+        // See if we are in a new section of the alphabet
+        char sw = ctor.name_.charAt(0);
+        if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) {
+            res = sw;
+            // Add the named anchor for this new letter
+            h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>");
+            if (sw == '_')
+                h_.writeText("<br><b>underscore</b>&nbsp;");
+            else
+                h_.writeText("<br><font size=\"+2\">" + Character.toUpperCase(sw) + "</font>&nbsp;");
+            generateLetterIndex(ctorNames, sw, false);
+        }
+        // Deal with displaying duplicate indexes
+        if (multipleMarker == 1) {
+            h_.writeText("<i>" + ctor.name_ + "</i><br>");
+        }
+        if (multipleMarker != 0)
+            h_.indent(INDENT_SIZE);
+        // Deal with each type of difference
+        // The output displayed for unique or duplicate entries is the same
+        // for constructors.
+        if (ctor.changeType_ == 0) {
+            String commentID = className + ".ctor_removed(" + type + ")";
+            h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\"><strike>" + ctor.name_ + "</strike>");
+            h_.emitTypeWithParens(shownType, false);
+            h_.writeText("</A></nobr>&nbsp;constructor<br>");
+        } else if (ctor.changeType_ == 1) {
+            String commentID = className + ".ctor_added(" + type + ")";
+            h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\"><b>" + ctor.name_ + "</b>");
+            h_.emitTypeWithParens(shownType, false);
+            h_.writeText("</A></nobr>&nbsp;constructor<br>");
+        } else if (ctor.changeType_ == 2) {
+            String commentID = className + ".ctor_changed(" + type + ")";
+            h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">" + ctor.name_);
+            h_.emitTypeWithParens(shownType, false);
+            h_.writeText("</A></nobr>&nbsp;constructor<br>");
+        }
+        return res;
+    }
+
+    /** 
+     * Emit the index of all methods, which appears in the bottom left frame. 
+     */
+    public void emitMethodsIndex(APIDiff apiDiff, int indexType) {
+        // Add all the names of methods to a new list, to be sorted later
+        methNames = new ArrayList(); // Index[]
+        boolean hasRemovals = false;
+        boolean hasAdditions = false;
+        boolean hasChanges = false;
+        Iterator iter = apiDiff.packagesChanged.iterator();
+        while (iter.hasNext()) {
+            PackageDiff pkgDiff = (PackageDiff)(iter.next());
+            String pkgName = pkgDiff.name_;
+            Iterator iterClass = pkgDiff.classesChanged.iterator();
+            while (iterClass.hasNext()) {
+                ClassDiff classDiff = (ClassDiff)(iterClass.next());
+                if (classDiff.methodsRemoved.size() != 0)
+                    hasRemovals = true;
+                if (classDiff.methodsAdded.size() != 0)
+                    hasAdditions = true;
+                if (classDiff.methodsChanged.size() != 0)
+                    hasChanges = true;
+                recordDiffs(hasRemovals, hasAdditions, hasChanges);
+                String className = classDiff.name_;
+                Iterator iterMeth = classDiff.methodsRemoved.iterator();
+                while ((indexType == 3 || indexType == 0) && iterMeth.hasNext()) {
+                    MethodAPI meth = (MethodAPI)(iterMeth.next());
+                    methNames.add(new Index(meth.name_, 0, pkgName, className, meth.getSignature()));
+                }
+                iterMeth = classDiff.methodsAdded.iterator();
+                while ((indexType == 3 || indexType == 1) && iterMeth.hasNext()) {
+                    MethodAPI meth = (MethodAPI)(iterMeth.next());
+                    Index idx = new Index(meth.name_, 1, pkgName, className, meth.getSignature());
+                    idx.doc_ = meth.doc_; // Used for checking @since
+                    methNames.add(idx);
+                }
+                iterMeth = classDiff.methodsChanged.iterator();
+                while ((indexType == 3 || indexType == 2) && iterMeth.hasNext()) {
+                    MemberDiff meth = (MemberDiff)(iterMeth.next());
+                    methNames.add(new Index(meth.name_, 2, pkgName, className, meth.newSignature_));
+                }
+            }
+        }
+        Collections.sort(methNames);
+        emitIndexHeader("Methods", indexType, hasRemovals, hasAdditions, hasChanges);
+        emitIndexEntries(methNames.iterator());
+        if (indexType == 1)
+            emitMissingSinces(methNames.iterator());
+    }
+
+    /** Emit an index entry for a method. */
+    public char emitMethodIndexEntry(Index meth, char oldsw, 
+                                     int multipleMarker) {
+        char res = oldsw;
+        String className = meth.pkgName_ + "." + meth.className_;
+        String memberRef = meth.pkgName_ + "." + meth.className_;
+        String type = meth.type_;
+        if (type.compareTo("void") == 0)
+            type = "";
+        String shownType = HTMLReportGenerator.simpleName(type);
+        // See if we are in a new section of the alphabet
+        char sw = meth.name_.charAt(0);
+        if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) {
+            res = sw;
+            // Add the named anchor for this new letter
+            h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>");
+            if (sw == '_')
+                h_.writeText("<br><b>underscore</b>&nbsp;");
+            else
+                h_.writeText("<br><font size=\"+2\">" + Character.toUpperCase(sw) + "</font>&nbsp;");
+            generateLetterIndex(methNames, sw, false);
+        }
+        // Deal with displaying duplicate indexes
+        if (multipleMarker == 1) {
+            h_.writeText("<i>" + meth.name_ + "</i><br>");
+        }
+        if (multipleMarker != 0)
+            h_.indent(INDENT_SIZE);
+        // Deal with each type of difference
+        if (meth.changeType_ == 0) {
+            String commentID = className + "." + meth.name_ + "_removed(" + type + ")";                    
+            if (multipleMarker == 0) {
+                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\"><strike>" + meth.name_ + "</strike>");
+                h_.emitTypeWithParens(shownType, false);
+            } else {
+                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">type&nbsp;<strike>");
+                h_.emitTypeWithParens(shownType, false);
+                h_.writeText("</strike>&nbsp;in&nbsp;" + className);
+            }
+            h_.writeText("</A></nobr><br>");
+        } else if (meth.changeType_ == 1) {
+            String commentID = className + "." + meth.name_ + "_added(" + type + ")";                    
+            if (multipleMarker == 0) {
+                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\"><b>" + meth.name_ + "</b>");
+                h_.emitTypeWithParens(shownType, false);
+            } else {
+                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">type&nbsp;<b>");
+                h_.emitTypeWithParens(shownType, false);
+                h_.writeText("</b>&nbsp;in&nbsp;" + className);
+            }
+            h_.writeText("</A></nobr><br>");
+        } else if (meth.changeType_ == 2) {
+            String commentID = className + "." + meth.name_ + "_changed(" + type + ")";                    
+            if (multipleMarker == 0) {
+                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">" + meth.name_);
+                h_.emitTypeWithParens(shownType, false);
+            } else {
+                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">type&nbsp;");
+                h_.emitTypeWithParens(shownType, false);
+                h_.writeText("&nbsp;in&nbsp;" + className);
+            }
+            h_.writeText("</A></nobr><br>");
+        }
+        return res;
+    }
+
+    /** 
+     * Emit the index of all fields, which appears in the bottom left frame. 
+     */
+    public void emitFieldsIndex(APIDiff apiDiff, int indexType) {
+        // Add all the names of fields to a new list, to be sorted later
+        fieldNames = new ArrayList(); // Index[]
+        boolean hasRemovals = false;
+        boolean hasAdditions = false;
+        boolean hasChanges = false;
+        Iterator iter = apiDiff.packagesChanged.iterator();
+        while (iter.hasNext()) {
+            PackageDiff pkgDiff = (PackageDiff)(iter.next());
+            String pkgName = pkgDiff.name_;
+            Iterator iterClass = pkgDiff.classesChanged.iterator();
+            while (iterClass.hasNext()) {
+                ClassDiff classDiff = (ClassDiff)(iterClass.next());
+                if (classDiff.fieldsRemoved.size() != 0)
+                    hasRemovals = true;
+                if (classDiff.fieldsAdded.size() != 0)
+                    hasAdditions = true;
+                if (classDiff.fieldsChanged.size() != 0)
+                    hasChanges = true;
+                recordDiffs(hasRemovals, hasAdditions, hasChanges);
+                String className = classDiff.name_;
+                Iterator iterField = classDiff.fieldsRemoved.iterator();
+                while ((indexType == 3 || indexType == 0) && iterField.hasNext()) {
+                    FieldAPI fld = (FieldAPI)(iterField.next());
+                    fieldNames.add(new Index(fld.name_, 0, pkgName, className, fld.type_, true));
+                }
+                iterField = classDiff.fieldsAdded.iterator();
+                while ((indexType == 3 || indexType == 1) && iterField.hasNext()) {
+                    FieldAPI fld = (FieldAPI)(iterField.next());
+                    Index idx = new Index(fld.name_, 1, pkgName, className, fld.type_, true);
+                    idx.doc_ = fld.doc_; // Used for checking @since
+                    fieldNames.add(idx);
+                }
+                iterField = classDiff.fieldsChanged.iterator();
+                while ((indexType == 3 || indexType == 2) && iterField.hasNext()) {
+                    MemberDiff fld = (MemberDiff)(iterField.next());
+                    fieldNames.add(new Index(fld.name_, 2, pkgName, className, fld.newType_, true));
+                }
+            }
+        }
+        Collections.sort(fieldNames);
+        emitIndexHeader("Fields", indexType, hasRemovals, hasAdditions, hasChanges);
+        emitIndexEntries(fieldNames.iterator());
+        if (indexType == 1)
+            emitMissingSinces(fieldNames.iterator());
+    }
+
+    /** Emit an index entry for a field. */
+    public char emitFieldIndexEntry(Index fld, char oldsw, 
+                                    int multipleMarker) {
+        char res = oldsw;
+        String className = fld.pkgName_ + "." + fld.className_;
+        String memberRef = fld.pkgName_ + "." + fld.className_;
+        String type = fld.type_;
+        if (type.compareTo("void") == 0)
+            type = "";
+        String shownType = HTMLReportGenerator.simpleName(type);
+        // See if we are in a new section of the alphabet
+        char sw = fld.name_.charAt(0);
+        if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) {
+            res = sw;
+            // Add the named anchor for this new letter
+            h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>");
+            if (sw == '_')
+                h_.writeText("<br><b>underscore</b>&nbsp;");
+            else
+                h_.writeText("<br><font size=\"+2\">" + Character.toUpperCase(sw) + "</font>&nbsp;");
+            generateLetterIndex(fieldNames, sw, false);
+        }
+        // Deal with displaying duplicate indexes
+        if (multipleMarker == 1) {
+            h_.writeText("<i>" + fld.name_ + "</i><br>");
+        }
+        if (multipleMarker != 0) {
+// More context than this is helpful here: h_.indent(INDENT_SIZE);
+            h_.writeText("&nbsp;in&nbsp;");
+        }
+        // Deal with each type of difference
+        if (fld.changeType_ == 0) {
+            String commentID = className + "." + fld.name_;                    
+            if (multipleMarker == 0) {            
+                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\"><strike>" + fld.name_ + "</strike></A>");
+                h_.writeText("</nobr><br>");
+            } else {
+                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\"><strike>" + className + "</strike></A>");
+                h_.writeText("</nobr><br>");
+            }
+        } else if (fld.changeType_ == 1) {
+            String commentID = className + "." + fld.name_;                    
+            if (multipleMarker == 0) {            
+                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">" + fld.name_ + "</A>");
+                h_.writeText("</nobr><br>");
+            } else {
+                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">" + className + "</A>");
+                h_.writeText("</nobr><br>");
+            }
+        } else if (fld.changeType_ == 2) {
+            String commentID = className + "." + fld.name_;                    
+            if (multipleMarker == 0) {            
+                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">" + fld.name_ + "</A>");
+                h_.writeText("</nobr><br>");
+            } else {
+                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">" + className + "</A>");
+                h_.writeText("</nobr><br>");
+            }
+        }
+        return res;
+    }
+
+    /** 
+     * Emit the index of all changes, which appears in the bottom left frame.
+     * Has to be run after all the other indexes have been written, since it
+     * uses data from when they are generated.
+     */
+    public void emitAllDiffsIndex(APIDiff apiDiff, int indexType) {
+        allNames = new ArrayList(); // Index[]
+        // Add all the changes into one big list, and sort it by name,
+        // ignoring case
+        allNames.addAll(packageNames);
+        allNames.addAll(classNames);
+        allNames.addAll(ctorNames);
+        allNames.addAll(methNames);
+        allNames.addAll(fieldNames);
+        // Compares two Index objects' names, ignoring case differences.
+        Collections.sort(allNames);
+
+        emitIndexHeader("All Differences", indexType, atLeastOneRemoval, 
+                        atLeastOneAddition, atLeastOneChange);
+
+        // Tell generateLetterIndex to use allNames as the list when 
+        // using the other methods to generate the indexes.
+        isAllNames = true; 
+        
+        // Now emit a line for each entry in the list in the appropriate 
+        // format for each program element
+        Iterator iter = allNames.iterator();
+        char oldsw = '\0';
+        int multipleMarker = 0;
+        Index currIndex = null; // The entry which is emitted
+        while (iter.hasNext()) {
+            // The next entry after the current one
+            Index nextIndex = (Index)(iter.next()); 
+            if (currIndex == null) {
+                currIndex = nextIndex; // Prime the pump
+            } else {
+                if (nextIndex.name_.compareTo(currIndex.name_) == 0) {
+                    // It's a duplicate index, so emit the name and then
+                    // the indented entries
+                    if (multipleMarker == 0)
+                        multipleMarker = 1; // Start of a duplicate index
+                    else if (multipleMarker == 1)
+                        multipleMarker = 2; // Inside a duplicate index
+                    oldsw = emitIndexEntryForAny(currIndex, oldsw, multipleMarker);
+                } else {
+                    if (multipleMarker == 1)
+                        multipleMarker = 2; // Inside a duplicate index
+                    oldsw = emitIndexEntryForAny(currIndex, oldsw, multipleMarker);
+                    multipleMarker = 0; // Not in a duplicate index any more
+                }
+                currIndex = nextIndex;
+            }
+        }
+        // Emit the last entry left in currIndex
+        if (multipleMarker == 1)
+            multipleMarker = 2; // Inside a duplicate index
+        if (currIndex != null)
+            oldsw = emitIndexEntryForAny(currIndex, oldsw, multipleMarker);
+
+        // Tell generateLetterIndex to stop using allNames as the list when 
+        // using the other methods to generate the indexes.
+        isAllNames = false; 
+    }
+
+    /** Call the appropriate *IndexEntry method for each entry. */
+    public char emitIndexEntryForAny(Index currIndex, char oldsw, 
+                                     int multipleMarker) {
+        if (currIndex.ename_.compareTo("package") == 0) {
+            h_.writeText("<!-- Package " + currIndex.name_ + " -->");
+            return emitPackageIndexEntry(currIndex, oldsw);
+        } else if (currIndex.ename_.compareTo("class") == 0) {
+            h_.writeText("<!-- Class " + currIndex.name_ + " -->");
+            return emitClassIndexEntry(currIndex, oldsw, multipleMarker);
+        } else if (currIndex.ename_.compareTo("constructor") == 0) {
+            h_.writeText("<!-- Constructor " + currIndex.name_ + " -->");
+            return emitCtorIndexEntry(currIndex, oldsw, multipleMarker);
+        } else if (currIndex.ename_.compareTo("method") == 0) {
+            h_.writeText("<!-- Method " + currIndex.name_ + " -->");
+            return emitMethodIndexEntry(currIndex, oldsw, multipleMarker);
+        } else if (currIndex.ename_.compareTo("field") == 0) {
+            h_.writeText("<!-- Field " + currIndex.name_ + " -->");
+            return emitFieldIndexEntry(currIndex, oldsw, multipleMarker);
+        }
+        return '\0';
+    }
+
+    /** The list of all changes for all program elements. */
+    private List allNames = null; // Index[]
+
+    /** The list of all package changes. */
+    private List packageNames = null; // Index[]
+
+    /** The list of all class changes. */
+    private List classNames = null; // Index[]
+
+    /** The list of all constructor changes. */
+    private List ctorNames = null; // Index[]
+
+    /** The list of all method changes. */
+    private List methNames = null; // Index[]
+
+    /** The list of all field changes. */
+    private List fieldNames = null; // Index[]
+
+    /** If set, then use allNames to generate the letter indexes. */
+    private boolean isAllNames = false;
+
+    /** 
+     * If any of the parameters are set, then set the respective atLeastOne
+     * variable, used to generate the links at the top of the allDiffs index. 
+     * Never unset an atLeastOne variable.
+     */
+    private void recordDiffs(boolean hasRemovals, boolean hasAdditions, 
+                        boolean hasChanges) {
+        if (hasRemovals)
+            atLeastOneRemoval = true;
+        if (hasAdditions)
+            atLeastOneAddition = true;
+        if (hasChanges)
+            atLeastOneChange = true;
+    }
+
+    /** Set if there was at least one removal in the entire API. */
+    private boolean atLeastOneRemoval = false;
+
+    /** Set if there was at least one addition in the entire API. */
+    private boolean atLeastOneAddition = false;
+
+    /** Set if there was at least one change in the entire API. */
+    private boolean atLeastOneChange = false;
+
+    /** 
+     * The number of non-breaking spaces to indent a duplicate indexes'
+     * entries by. 
+     */
+    private final int INDENT_SIZE = 2;
+}
+
+/**
+ * Class used to produce indexes of packages and classes. 
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+class Index implements Comparable {
+
+    /** The name of the program element this Index object represents. */
+    public String ename_ = null;
+
+    /** Name of the changed package, class or member. */
+    public String name_ = null;
+    
+    /** Type of change. 0 = remove, 1 = add, 2 = change. */
+    public int changeType_;
+    
+    /** Name of the changed package if name_ is a class name. */
+    public String pkgName_ = null;
+    
+    /** Set if this class is an interface. */
+    public boolean isInterface_= false;
+    
+    /** The doc block of added elements, default is null. */
+    public String doc_ = null;
+    
+    /** 
+     * The new member type. For methods, this is the signature.
+     */
+    public String type_ = null;
+
+    /** 
+     * The class name. Only used by methods.
+     */
+    public String className_ = null;
+
+    /** Constructor for packages. */
+    public Index(String name, int changeType) {
+        ename_ = "package";
+        name_ = name;
+        changeType_ = changeType;
+    }
+    
+    /** Constructor for classes. */
+    public Index(String name, int changeType, String pkgName, boolean isInterface) {
+        ename_ = "class";
+        name_ = name;
+        changeType_ = changeType;
+        pkgName_ = pkgName;
+        isInterface_ = isInterface;
+    }
+        
+    /** Constructor for constructors. */
+    public Index(String name, int changeType, String pkgName, String type) {
+        ename_ = "constructor";
+        name_ = name;
+        changeType_ = changeType;
+        pkgName_ = pkgName;
+        type_  = type;
+    }
+        
+    /** Constructor for methods. */
+    public Index(String name, int changeType, String pkgName, 
+                 String className, String type) {
+        ename_ = "method";
+        name_ = name;
+        changeType_ = changeType;
+        pkgName_ = pkgName;
+        className_ = className;
+        type_  = type;
+    }
+        
+    /** 
+     * Constructor for fields. 
+     *
+     * The boolean <code>fld</code> is simply there to differentiate this
+     * constructor from the one for methods.
+     */
+    public Index(String name, int changeType, String pkgName, 
+                 String className, String type, boolean fld) {
+        ename_ = "field";
+        name_ = name;
+        changeType_ = changeType;
+        pkgName_ = pkgName;
+        className_ = className;
+        type_  = type;
+    }
+        
+        
+    /** Compare two Index objects by their simple names, ignoring case. */
+    public int compareTo(Object o) {
+        return name_.compareToIgnoreCase(((Index)o).name_);
+    }  
+    
+}
+
diff --git a/src/jdiff/HTMLReportGenerator.java b/src/jdiff/HTMLReportGenerator.java
new file mode 100755
index 0000000..f6cf861
--- /dev/null
+++ b/src/jdiff/HTMLReportGenerator.java
@@ -0,0 +1,2163 @@
+package jdiff;
+
+import java.util.*;
+import java.io.*;
+import java.text.*;
+
+/**
+ * Emit HTML based on the changes between two sets of APIs.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+public class HTMLReportGenerator {
+
+    /** Default constructor. */
+    public HTMLReportGenerator() {
+    }   
+
+    /** The Comments object for existing comments. */
+    private Comments existingComments_ = null;
+
+    /** 
+     * The Comments object for freshly regenerated comments. 
+     * This is populated during the generation of the report,
+     * and should be like existingComments_ but with unused comments
+     * marked as such, so that they can be commented out in XML when 
+     * the new comments are written out to the comments file.
+     */
+    private Comments newComments_ = null;
+
+    /** 
+     * Accessor method for the freshly generated Comments object. 
+     * The list of comments is sorted before the object is returned.
+     */
+    public Comments getNewComments() {
+        Collections.sort(newComments_.commentsList_);
+        return newComments_;
+    }
+
+    /** Generate the report. */
+    public void generate(APIComparator comp, Comments existingComments) {
+        String fullReportFileName = reportFileName;
+        if (outputDir != null)
+            fullReportFileName = outputDir + JDiff.DIR_SEP + reportFileName;
+        System.out.println("JDiff: generating HTML report into the file '" + fullReportFileName + reportFileExt + "' and the subdirectory '" + fullReportFileName + "'");
+        // May be null if no comments file exists yet
+        existingComments_ = existingComments;
+        // Where the new comments will be placed
+        newComments_ = new Comments();
+        // Writing to multiple files, so make sure the subdirectory exists
+        File opdir = new File(fullReportFileName);
+        if (!opdir.mkdir() && !opdir.exists()) {
+            System.out.println("Error: could not create the subdirectory '" + fullReportFileName + "'");
+            System.exit(3);
+        }
+
+        // Emit the documentation difference files
+        if (!Diff.noDocDiffs) {
+            // Documentation differences, one file per package
+            Diff.emitDocDiffs(fullReportFileName);
+        }
+
+        // This is the top-level summary file, first in the right hand frame
+        // or linked at the start to if no frames are used.
+        String changesSummaryName = fullReportFileName + JDiff.DIR_SEP +
+            reportFileName + "-summary" + reportFileExt;
+        apiDiff = comp.apiDiff;
+        try {
+            FileOutputStream fos = new FileOutputStream(changesSummaryName);
+            reportFile = new PrintWriter(fos);
+            writeStartHTMLHeader();
+            // Write out the title in he HTML header
+            String oldAPIName = "Old API";
+            if (apiDiff.oldAPIName_ != null)
+                oldAPIName = apiDiff.oldAPIName_;
+            String newAPIName = "New API";
+            if (apiDiff.newAPIName_ != null)
+                newAPIName = apiDiff.newAPIName_;
+            if (windowTitle == null) 
+                writeHTMLTitle("Android API Differences Report");
+            else
+                writeHTMLTitle(windowTitle);
+            writeStyleSheetRef();
+            writeText("</HEAD>");
+
+            writeText("<body class=\"gc-documentation\">");
+
+           // writeText("<div class=\"g-section g-tpl-180\">");
+           // Add the nav bar for the summary page
+            writeNavigationBar(reportFileName + "-summary", null, null, 
+                               null, 0, true,
+                               apiDiff.packagesRemoved.size() != 0, 
+                               apiDiff.packagesAdded.size() != 0,
+                               apiDiff.packagesChanged.size() != 0);
+            
+            // Write the title in the body with some formatting
+            if (docTitle == null) {
+	                //writeText("<center>");        
+                writeText("  <div id=\"titleAligner\" style=\"vertical-align:top;padding:1em;margin-left:0;text-align:left;\">");
+                writeText("    <H1 class=\"pagecontenth1\">API&nbsp;Differences&nbsp;Report</H1>");
+                writeText("  </div>");
+            } else {
+                writeText("  <div id=\"titleAligner\" style=\"vertical-align:top;padding:1em;margin-left:0;text-align:left;\">");
+                writeText("    <H1 class=\"pagecontenth1\">" + docTitle + "</H1>");
+                writeText("  </div>");
+            }
+
+            writeText("<p>This document details the changes in the Android framework API. It shows ");
+            writeText("additions, modifications, and removals for packages, classes, methods, and "); 
+            writeText("fields. Each reference to an API change includes a brief description of the ");
+            writeText("API and an explanation of the change and suggested workaround, where available.</p>");
+
+            writeText("<p>The differences described in this report are based a comparison of the APIs ");
+            writeText("whose versions are specified in the upper-right corner of this page. It compares a ");
+            writeText("newer \"to\" API to an older \"from\" version, noting any changes relative to the ");
+            writeText("older API. So, for example, indicated API removals are no longer present in the \"to\" ");
+            writeText("API.</p>");
+
+            writeText("<p>To navigate the report, use the \"Select a Diffs Index\" and \"Filter the Index\" ");
+            writeText("controls on the left. The report uses text formatting to indicate <em>interface names</em>, ");
+            writeText("<a href= ><tt>links to reference documentation</tt></a>, and <a href= >links to change ");
+            writeText("description</a>. </p>");
+
+            writeText("<p>For more information about the Android framework API and SDK, ");
+            writeText("see the <a href=\"http://code.google.com/android/index.html\" target=\"_top\">Android product site</a>.</p>");
+
+            // Write the contents and the other files as well
+            writeReport(apiDiff);
+            writeHTMLFooter();
+            reportFile.close();
+        } catch(IOException e) {
+            System.out.println("IO Error while attempting to create " + changesSummaryName);
+            System.out.println("Error: " + e.getMessage());
+            System.exit(1);
+        }
+
+        // Now generate all the other files for multiple frames.
+        //
+        // The top-level changes.html frames file where everything starts.
+        String tln = fullReportFileName + reportFileExt;
+        // The file for the top-left frame.
+        String tlf = fullReportFileName + JDiff.DIR_SEP + 
+            "jdiff_topleftframe" + reportFileExt;
+        // The default file for the bottom-left frame is the one with the
+        // most information in it.
+        String allDiffsIndexName = fullReportFileName + JDiff.DIR_SEP + 
+            "alldiffs_index"; 
+        // Other indexes for the bottom-left frame.
+        String packagesIndexName = fullReportFileName + JDiff.DIR_SEP + 
+            "packages_index"; 
+        String classesIndexName = fullReportFileName + JDiff.DIR_SEP + 
+            "classes_index"; 
+        String constructorsIndexName = fullReportFileName + JDiff.DIR_SEP + 
+            "constructors_index"; 
+        String methodsIndexName = fullReportFileName + JDiff.DIR_SEP + 
+            "methods_index"; 
+        String fieldsIndexName = fullReportFileName + JDiff.DIR_SEP + 
+            "fields_index"; 
+
+        HTMLFiles hf = new HTMLFiles(this);
+        hf.emitTopLevelFile(tln, apiDiff);
+        hf.emitTopLeftFile(tlf);
+        hf.emitHelp(fullReportFileName, apiDiff);
+        hf.emitStylesheet();
+
+        HTMLIndexes h = new HTMLIndexes(this);
+        h.emitAllBottomLeftFiles(packagesIndexName, classesIndexName, 
+                            constructorsIndexName, methodsIndexName,
+                            fieldsIndexName, allDiffsIndexName, apiDiff);
+
+        if (doStats) {
+            // The file for the statistical report.
+            String sf = fullReportFileName + JDiff.DIR_SEP + 
+                "jdiff_statistics" + reportFileExt;
+            HTMLStatistics stats = new HTMLStatistics(this);
+            stats.emitStatistics(sf, apiDiff);
+        }
+    }   
+
+    /** 
+     * Write the HTML report. 
+     *
+     * The top section describes all the packages added (with links) and 
+     * removed, and the changed packages section has links which takes you 
+     * to a section for each package. This pattern continues for classes and
+     * constructors, methods and fields.
+     */
+    public void writeReport(APIDiff apiDiff) {
+
+        // Report packages which were removed in the new API
+        if (apiDiff.packagesRemoved.size() != 0) {
+            writeTableStart("Removed Packages", 2);
+            Iterator iter = apiDiff.packagesRemoved.iterator();
+            while (iter.hasNext()) {
+                PackageAPI pkgAPI = (PackageAPI)(iter.next());
+                String pkgName = pkgAPI.name_;
+                if (trace) System.out.println("Package " + pkgName + " was removed.");
+                writePackageTableEntry(pkgName, 0, pkgAPI.doc_, false);
+            }
+            writeTableEnd();
+        }
+        
+        // Report packages which were added in the new API
+        if (apiDiff.packagesAdded.size() != 0) {
+            writeTableStart("Added Packages", 2);
+            Iterator iter = apiDiff.packagesAdded.iterator();
+            while (iter.hasNext()) {
+                PackageAPI pkgAPI = (PackageAPI)(iter.next());
+                String pkgName = pkgAPI.name_;
+                if (trace) System.out.println("Package " + pkgName + " was added.");
+                writePackageTableEntry(pkgName, 1, pkgAPI.doc_, false);
+            }
+            writeTableEnd();
+        }
+
+        // Report packages which were changed in the new API
+        if (apiDiff.packagesChanged.size() != 0) {
+            // Emit a table of changed packages, with links to the file
+            // for each package.
+            writeTableStart("Changed Packages", 3);
+            Iterator iter = apiDiff.packagesChanged.iterator();
+            while (iter.hasNext()) {
+                PackageDiff pkgDiff = (PackageDiff)(iter.next());
+                String pkgName = pkgDiff.name_;
+                if (trace) System.out.println("Package " + pkgName + " was changed.");
+                writePackageTableEntry(pkgName, 2, null, false);
+            }
+            writeTableEnd();
+            writeText("<!-- End of API section -->");
+
+            // Now emit a separate file for each changed package.
+            writeText("<!-- Start of packages section -->");
+            PackageDiff[] pkgDiffs = new PackageDiff[apiDiff.packagesChanged.size()];
+            pkgDiffs = (PackageDiff[])apiDiff.packagesChanged.toArray(pkgDiffs);
+            for (int i = 0; i < pkgDiffs.length; i++) {
+                reportChangedPackage(pkgDiffs, i);
+            }
+        }
+            writeText("</div><!-- end pagecontent -->");
+            writeText("</div><!-- end codesitecontent -->");
+            writeText("<div style=\"padding-left: 10px; padding-right: 10px; margin-top: 0; padding-bottom: 15px;\">");
+            writeText("  <table style=\"width: 100%; border: none;\"><tr>");
+            writeText("    <td style=\"text-align:center;font-size: 10pt; border: none; color: ccc;\"> ");
+            writeText("      <span>&copy;2008 Google - ");
+            writeText("            <a href=\"http://code.google.com\">Code Home</a> - ");
+            writeText("            <a href=\"http://www.google.com/accounts/TOS\">Site Terms of Service</a> - "); 
+            writeText("            <a href=\"http://www.google.com/privacy.html\">Privacy Policy</a> ");
+            writeText("      </span>");
+            writeText("      <div style=\"position:relative;margin-top:-2em;" );
+            writeText("        font-size:8pt;color:aaa;text-align:right;\">");
+            writeText("        <em>Generated by <a href=\"http://www.jdiff.org/\">JDiff</a></em><br><img ");
+            writeText("        align=\"right\" src=\"../../../assets/jdiff_logo.gif\">");
+            writeText("      </span>");
+            writeText("    </td>");
+            writeText(" </tr></table>");
+            writeText("</div>");
+            writeText("</div><!-- end gc-containter -->");
+}
+    
+    /** 
+     * Write out the details of a changed package in a separate file. 
+     */
+    public void reportChangedPackage(PackageDiff[] pkgDiffs, int pkgIndex) {
+        PackageDiff pkgDiff = pkgDiffs[pkgIndex];
+        String pkgName = pkgDiff.name_;
+
+        PrintWriter oldReportFile = null;
+        oldReportFile = reportFile;
+        String localReportFileName = null;
+        try {
+            // Prefix package files with pkg_ because there may be a class
+            // with the same name.
+            localReportFileName = reportFileName + JDiff.DIR_SEP + "pkg_" + pkgName + reportFileExt;
+            if (outputDir != null)
+                localReportFileName = outputDir + JDiff.DIR_SEP + localReportFileName;
+            FileOutputStream fos = new FileOutputStream(localReportFileName);
+            reportFile = new PrintWriter(fos);
+            writeStartHTMLHeader();
+            writeHTMLTitle(pkgName);
+            writeStyleSheetRef();
+            writeText("</HEAD>");
+            writeText("<BODY>");
+        } catch(IOException e) {
+            System.out.println("IO Error while attempting to create " + localReportFileName);
+            System.out.println("Error: "+ e.getMessage());
+            System.exit(1);
+        }
+
+        String pkgRef = pkgName;
+        pkgRef = pkgRef.replace('.', '/');
+        pkgRef = newDocPrefix + pkgRef + "/package-summary";
+        // A link to the package in the new API
+        String linkedPkgName = "<A HREF=\"" + pkgRef + ".html\" target=\"_top\"><font size=\"+1\"><tt>" + pkgName + "</tt></font></A>";
+        String prevPkgRef = null;
+        if (pkgIndex != 0) {
+            prevPkgRef = "pkg_" + pkgDiffs[pkgIndex-1].name_ + reportFileExt;
+        }
+        // Create the HTML link to the next package
+        String nextPkgRef = null;
+        if (pkgIndex < pkgDiffs.length - 1) {
+            nextPkgRef = "pkg_" + pkgDiffs[pkgIndex+1].name_ + reportFileExt;
+        }
+        
+        writeSectionHeader("Package " + linkedPkgName, pkgName, 
+                           prevPkgRef, nextPkgRef,
+                           null, 1,
+                           pkgDiff.classesRemoved.size() != 0, 
+                           pkgDiff.classesAdded.size() != 0,
+                           pkgDiff.classesChanged.size() != 0);
+
+        // Report changes in documentation
+        if (reportDocChanges && pkgDiff.documentationChange_ != null) {
+            String pkgDocRef = pkgName + "/package-summary";
+            pkgDocRef = pkgDocRef.replace('.', '/');
+            String oldPkgRef = pkgDocRef;
+            String newPkgRef = pkgDocRef;
+            if (oldDocPrefix != null)
+                oldPkgRef = oldDocPrefix + oldPkgRef;
+            else 
+                oldPkgRef = null;
+            newPkgRef = newDocPrefix + newPkgRef;
+            if (oldPkgRef != null) 
+                pkgDiff.documentationChange_ += "<A HREF=\"" + oldPkgRef +
+                    ".html#package_description\" target=\"_self\"><font size=\"+1\"><tt>old</tt></font></A> to ";
+            else
+                pkgDiff.documentationChange_ += "<font size=\"+1\"><tt>old</tt></font> to ";
+            pkgDiff.documentationChange_ += "<A HREF=\"" + newPkgRef + 
+                ".html#package_description\" target=\"_self\"><font size=\"+1\"><tt>new</tt></font></A>. ";
+            writeText(pkgDiff.documentationChange_);
+        }
+
+        // Report classes which were removed in the new API
+        if (pkgDiff.classesRemoved.size() != 0) {
+            // Determine the title for this section
+            boolean hasClasses = false;
+            boolean hasInterfaces = false;
+            Iterator iter = pkgDiff.classesRemoved.iterator();
+            while (iter.hasNext()) {
+                ClassAPI classAPI = (ClassAPI)(iter.next());
+                if (classAPI.isInterface_)
+                    hasInterfaces = true;
+                else
+                    hasClasses = true;
+            }
+            if (hasInterfaces && hasClasses)
+                writeTableStart("Removed Classes and Interfaces", 2);
+            else if (!hasInterfaces && hasClasses)
+                     writeTableStart("Removed Classes", 2);
+            else if (hasInterfaces && !hasClasses)
+                     writeTableStart("Removed Interfaces", 2);
+            // Emit the table entries
+            iter = pkgDiff.classesRemoved.iterator();
+            while (iter.hasNext()) {
+                ClassAPI classAPI = (ClassAPI)(iter.next());
+                String className = classAPI.name_;
+                if (trace) System.out.println("Class/Interface " + className + " was removed.");
+                writeClassTableEntry(pkgName, className, 0, classAPI.isInterface_, classAPI.doc_, false);
+            }
+            writeTableEnd();
+        }
+        
+        // Report classes which were added in the new API
+        if (pkgDiff.classesAdded.size() != 0) {
+            // Determine the title for this section
+            boolean hasClasses = false;
+            boolean hasInterfaces = false;
+            Iterator iter = pkgDiff.classesAdded.iterator();
+            while (iter.hasNext()) {
+                ClassAPI classAPI = (ClassAPI)(iter.next());
+                if (classAPI.isInterface_)
+                    hasInterfaces = true;
+                else
+                    hasClasses = true;
+            }
+            if (hasInterfaces && hasClasses)
+                writeTableStart("Added Classes and Interfaces", 2);
+            else if (!hasInterfaces && hasClasses)
+                     writeTableStart("Added Classes", 2);
+            else if (hasInterfaces && !hasClasses)
+                     writeTableStart("Added Interfaces", 2);
+            // Emit the table entries
+            iter = pkgDiff.classesAdded.iterator();
+            while (iter.hasNext()) {
+                ClassAPI classAPI = (ClassAPI)(iter.next());
+                String className = classAPI.name_;
+                if (trace) System.out.println("Class/Interface " + className + " was added.");
+                writeClassTableEntry(pkgName, className, 1, classAPI.isInterface_, classAPI.doc_, false);
+            }
+            writeTableEnd();
+        }
+
+        // Report classes which were changed in the new API
+        if (pkgDiff.classesChanged.size() != 0) {
+            // Determine the title for this section
+            boolean hasClasses = false;
+            boolean hasInterfaces = false;
+            Iterator iter = pkgDiff.classesChanged.iterator();
+            while (iter.hasNext()) {
+                ClassDiff classDiff = (ClassDiff)(iter.next());
+                if (classDiff.isInterface_)
+                    hasInterfaces = true;
+                else
+                    hasClasses = true;
+            }
+            if (hasInterfaces && hasClasses)
+                writeTableStart("Changed Classes and Interfaces", 2);
+            else if (!hasInterfaces && hasClasses)
+                     writeTableStart("Changed Classes", 2);
+            else if (hasInterfaces && !hasClasses)
+                     writeTableStart("Changed Interfaces", 2);
+            // Emit a table of changed classes, with links to the file
+            // for each class.
+            iter = pkgDiff.classesChanged.iterator();
+            while (iter.hasNext()) {
+                ClassDiff classDiff = (ClassDiff)(iter.next());
+                String className = classDiff.name_;
+                if (trace) System.out.println("Package " + pkgDiff.name_ + ", class/Interface " + className + " was changed.");
+                writeClassTableEntry(pkgName, className, 2, classDiff.isInterface_, null, false);
+            }
+            writeTableEnd();
+            // Now emit a separate file for each changed class and interface.
+            ClassDiff[] classDiffs = new ClassDiff[pkgDiff.classesChanged.size()];
+            classDiffs = (ClassDiff[])pkgDiff.classesChanged.toArray(classDiffs);
+            for (int k = 0; k < classDiffs.length; k++) {
+                reportChangedClass(pkgName, classDiffs, k);
+            }
+        }
+        
+        writeSectionFooter(pkgName, prevPkgRef, nextPkgRef, null, 1);
+        writeHTMLFooter();
+        reportFile.close();
+        reportFile = oldReportFile;
+    }
+
+    /** 
+     * Write out the details of a changed class in a separate file. 
+     */
+    public void reportChangedClass(String pkgName, ClassDiff[] classDiffs, int classIndex) {
+        ClassDiff classDiff = classDiffs[classIndex];
+        String className = classDiff.name_;
+
+        PrintWriter oldReportFile = null;
+        oldReportFile = reportFile;
+        String localReportFileName = null;
+        try {
+            localReportFileName = reportFileName + JDiff.DIR_SEP + pkgName + "." + className + reportFileExt;
+            if (outputDir != null)
+                localReportFileName = outputDir + JDiff.DIR_SEP + localReportFileName;
+            FileOutputStream fos = new FileOutputStream(localReportFileName);
+            reportFile = new PrintWriter(fos);
+            writeStartHTMLHeader();
+            writeHTMLTitle(pkgName + "." + className);
+            writeStyleSheetRef();
+            writeText("</HEAD>");
+            writeText("<BODY>");
+        } catch(IOException e) {
+            System.out.println("IO Error while attempting to create " + localReportFileName);
+            System.out.println("Error: "+ e.getMessage());
+            System.exit(1);
+        }
+
+        String classRef = pkgName + "." + className;
+        classRef = classRef.replace('.', '/');
+        if (className.indexOf('.') != -1) {
+            classRef = pkgName + ".";
+            classRef = classRef.replace('.', '/');
+            classRef = newDocPrefix + classRef + className;
+        } else {
+            classRef = newDocPrefix + classRef;
+        }
+        // A link to the class in the new API
+        String linkedClassName = "<A HREF=\"" + classRef + ".html\" target=\"_top\"><font size=\"+1\"><tt>" + className + "</tt></font></A>";
+        String lcn = pkgName + "." + linkedClassName;
+        //Links to the previous and next classes
+        String prevClassRef = null;
+        if (classIndex != 0) {
+            prevClassRef = pkgName + "." + classDiffs[classIndex-1].name_ + reportFileExt;
+        }
+        // Create the HTML link to the next package
+        String nextClassRef = null;
+        if (classIndex < classDiffs.length - 1) {
+            nextClassRef = pkgName + "." + classDiffs[classIndex+1].name_ + reportFileExt;
+        }
+
+        if (classDiff.isInterface_)
+            lcn = "Interface " + lcn;
+        else
+            lcn = "Class " + lcn;
+        boolean hasCtors = classDiff.ctorsRemoved.size() != 0 ||
+            classDiff.ctorsAdded.size() != 0 ||
+            classDiff.ctorsChanged.size() != 0;
+        boolean hasMethods = classDiff.methodsRemoved.size() != 0 ||
+            classDiff.methodsAdded.size() != 0 ||
+            classDiff.methodsChanged.size() != 0;
+        boolean hasFields = classDiff.fieldsRemoved.size() != 0 ||
+            classDiff.fieldsAdded.size() != 0 ||
+            classDiff.fieldsChanged.size() != 0;
+        writeSectionHeader(lcn, pkgName, prevClassRef, nextClassRef, 
+                           className, 2,
+                           hasCtors, hasMethods, hasFields);
+
+        if (classDiff.inheritanceChange_ != null)
+            writeText("<p><font xsize=\"+1\">" + classDiff.inheritanceChange_ + "</font>");
+
+        // Report changes in documentation
+        if (reportDocChanges && classDiff.documentationChange_ != null) {
+            String oldClassRef = null;
+            if (oldDocPrefix != null) {
+                oldClassRef = pkgName + "." + className;
+                oldClassRef = oldClassRef.replace('.', '/');
+                if (className.indexOf('.') != -1) {
+                    oldClassRef = pkgName + ".";
+                    oldClassRef = oldClassRef.replace('.', '/');
+                    oldClassRef = oldDocPrefix + oldClassRef + className;
+                } else {
+                    oldClassRef = oldDocPrefix + oldClassRef;
+                }
+            }
+            if (oldDocPrefix != null) 
+                classDiff.documentationChange_ += "<A HREF=\"" + oldClassRef +
+                    ".html\" target=\"_self\"><font size=\"+1\"><tt>old</tt></font></A> to ";
+            else
+                classDiff.documentationChange_ += "<font size=\"+1\"><tt>old</tt></font> to ";
+            classDiff.documentationChange_ += "<A HREF=\"" + classRef + 
+                ".html\" target=\"_self\"><font size=\"+1\"><tt>new</tt></font></A>. ";
+            writeText(classDiff.documentationChange_);
+        }
+
+        if (classDiff.modifiersChange_ != null)
+            writeText("<p>" + classDiff.modifiersChange_);
+
+        reportAllCtors(pkgName, classDiff);
+        reportAllMethods(pkgName, classDiff);
+        reportAllFields(pkgName, classDiff);
+
+        writeSectionFooter(pkgName, prevClassRef, nextClassRef, className, 2);
+        writeHTMLFooter();
+        reportFile.close();
+        reportFile = oldReportFile;
+    }
+
+    /** 
+     * Write out the details of constructors in a class. 
+     */
+    public void reportAllCtors(String pkgName, ClassDiff classDiff) {
+        String className = classDiff.name_;
+        writeText("<a NAME=\"constructors\"></a>"); // Named anchor
+        // Report ctors which were removed in the new API
+        if (classDiff.ctorsRemoved.size() != 0) {
+            writeTableStart("Removed Constructors", 2);
+            Iterator iter = classDiff.ctorsRemoved.iterator();
+            while (iter.hasNext()) {
+                ConstructorAPI ctorAPI = (ConstructorAPI)(iter.next());
+                String ctorType = ctorAPI.type_;
+                if (ctorType.compareTo("void") == 0)
+                    ctorType = "";
+                String id = className + "(" + ctorType + ")";
+                if (trace) System.out.println("Constructor " + id + " was removed.");
+                writeCtorTableEntry(pkgName, className, ctorType, 0, ctorAPI.doc_, false);
+            }
+            writeTableEnd();
+        }
+
+        // Report ctors which were added in the new API
+        if (classDiff.ctorsAdded.size() != 0) {
+            writeTableStart("Added Constructors", 2);
+            Iterator iter = classDiff.ctorsAdded.iterator();
+            while (iter.hasNext()) {
+                ConstructorAPI ctorAPI = (ConstructorAPI)(iter.next());
+                String ctorType = ctorAPI.type_;
+                if (ctorType.compareTo("void") == 0)
+                    ctorType = "";
+                String id = className + "(" + ctorType + ")";
+                if (trace) System.out.println("Constructor " + id + " was added.");
+                writeCtorTableEntry(pkgName, className, ctorType, 1, ctorAPI.doc_, false);
+            }
+            writeTableEnd();
+        }
+        
+        // Report ctors which were changed in the new API
+        if (classDiff.ctorsChanged.size() != 0) {
+            // Emit a table of changed classes, with links to the section
+            // for each class.
+            writeTableStart("Changed Constructors", 3);
+            Iterator iter = classDiff.ctorsChanged.iterator();
+            while (iter.hasNext()) {
+                MemberDiff memberDiff = (MemberDiff)(iter.next());
+                if (trace) System.out.println("Constructor for " + className +
+                    " was changed from " + memberDiff.oldType_ + " to " + 
+                    memberDiff.newType_);
+                writeCtorChangedTableEntry(pkgName, className, memberDiff);
+            }
+            writeTableEnd();
+        }
+    }
+
+    /** 
+     * Write out the details of methods in a class. 
+     */
+    public void reportAllMethods(String pkgName, ClassDiff classDiff) {
+        writeText("<a NAME=\"methods\"></a>"); // Named anchor
+        String className = classDiff.name_;
+        // Report methods which were removed in the new API
+        if (classDiff.methodsRemoved.size() != 0) {
+            writeTableStart("Removed Methods", 2);
+            Iterator iter = classDiff.methodsRemoved.iterator();
+            while (iter.hasNext()) {
+                MethodAPI methodAPI = (MethodAPI)(iter.next());
+                String methodName = methodAPI.name_ + "(" + methodAPI.getSignature() + ")";
+                if (trace) System.out.println("Method " + methodName + " was removed.");
+                writeMethodTableEntry(pkgName, className, methodAPI, 0, methodAPI.doc_, false);
+            }
+            writeTableEnd();
+        }
+
+        // Report methods which were added in the new API
+        if (classDiff.methodsAdded.size() != 0) {
+            writeTableStart("Added Methods", 2);
+            Iterator iter = classDiff.methodsAdded.iterator();
+            while (iter.hasNext()) {
+                MethodAPI methodAPI = (MethodAPI)(iter.next());
+                String methodName = methodAPI.name_ + "(" + methodAPI.getSignature() + ")";
+                if (trace) System.out.println("Method " + methodName + " was added.");
+                writeMethodTableEntry(pkgName, className, methodAPI, 1, methodAPI.doc_, false);
+            }
+            writeTableEnd();
+        }
+        
+        // Report methods which were changed in the new API
+        if (classDiff.methodsChanged.size() != 0) {
+            // Emit a table of changed methods.
+            writeTableStart("Changed Methods", 3);
+            Iterator iter = classDiff.methodsChanged.iterator();
+            while (iter.hasNext()) {
+                MemberDiff memberDiff = (MemberDiff)(iter.next());
+                if (trace) System.out.println("Method " + memberDiff.name_ + 
+                      " was changed.");
+                writeMethodChangedTableEntry(pkgName, className, memberDiff);
+            }
+            writeTableEnd();
+        }
+    }
+
+    /** 
+     * Write out the details of fields in a class. 
+     */
+    public void reportAllFields(String pkgName, ClassDiff classDiff) {
+        writeText("<a NAME=\"fields\"></a>"); // Named anchor
+        String className = classDiff.name_;
+        // Report fields which were removed in the new API
+        if (classDiff.fieldsRemoved.size() != 0) {
+            writeTableStart("Removed Fields", 2);
+            Iterator iter = classDiff.fieldsRemoved.iterator();
+            while (iter.hasNext()) {
+                FieldAPI fieldAPI = (FieldAPI)(iter.next());
+                String fieldName = fieldAPI.name_;
+                if (trace) System.out.println("Field " + fieldName + " was removed.");
+                writeFieldTableEntry(pkgName, className, fieldAPI, 0, fieldAPI.doc_, false);
+            }
+            writeTableEnd();
+        }
+        
+        // Report fields which were added in the new API
+        if (classDiff.fieldsAdded.size() != 0) {
+            writeTableStart("Added Fields", 2);
+            Iterator iter = classDiff.fieldsAdded.iterator();
+            while (iter.hasNext()) {
+                FieldAPI fieldAPI = (FieldAPI)(iter.next());
+                String fieldName = fieldAPI.name_;
+                if (trace) System.out.println("Field " + fieldName + " was added.");
+                writeFieldTableEntry(pkgName, className, fieldAPI, 1, fieldAPI.doc_, false);
+            }
+            writeTableEnd();
+        }
+        
+        // Report fields which were changed in the new API
+        if (classDiff.fieldsChanged.size() != 0) {
+            // Emit a table of changed classes, with links to the section
+            // for each class.
+            writeTableStart("Changed Fields", 3);
+            Iterator iter = classDiff.fieldsChanged.iterator();
+            while (iter.hasNext()) {
+                MemberDiff memberDiff = (MemberDiff)(iter.next());
+                if (trace) System.out.println("Field " + pkgName + "." + className + "." + memberDiff.name_ + " was changed from " + memberDiff.oldType_ + " to " + memberDiff.newType_);
+                writeFieldChangedTableEntry(pkgName, className, memberDiff);
+            }
+            writeTableEnd();
+        }
+        
+    }
+
+    /** 
+     * Write the start of the HTML header, together with the current
+     * date and time in an HTML comment. 
+     */
+    public void writeStartHTMLHeaderWithDate() {
+        writeStartHTMLHeader(true);
+    }
+
+    /** Write the start of the HTML header. */
+    public void writeStartHTMLHeader() {
+        writeStartHTMLHeader(false);
+    }
+
+    /** Write the start of the HTML header. */
+    public void writeStartHTMLHeader(boolean addDate) {
+        writeText("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Frameset//EN\"\"" + RootDocToXML.baseURI + "/TR/REC-html40/frameset.dtd\">");
+        writeText("<HTML>");
+        writeText("<HEAD>");
+        writeText("<meta name=\"generator\" content=\"JDiff v" + JDiff.version + "\">");
+        writeText("<!-- Generated by the JDiff Javadoc doclet -->");
+        writeText("<!-- (" + JDiff.jDiffLocation + ") -->");
+        if (addDate)
+            writeText("<!-- on " + new Date() + " -->");
+        writeText("<meta name=\"description\" content=\"" + JDiff.jDiffDescription + "\">");
+        writeText("<meta name=\"keywords\" content=\"" + JDiff.jDiffKeywords + "\">");
+    }
+
+    /** Write the HTML title */
+    public void writeHTMLTitle(String title) {
+        writeText("<TITLE>");
+        writeText(title);
+        writeText("</TITLE>");
+    }
+
+    /** 
+     * Write the HTML style sheet reference for files in the subdirectory.
+     */
+    public void writeStyleSheetRef() {
+        writeStyleSheetRef(false);
+    }
+
+    /** 
+     * Write the HTML style sheet reference. If inSameDir is set, don't add
+     * "../" to the location.
+     */
+
+    public void writeStyleSheetRef(boolean inSameDir) {
+        if (inSameDir) {
+            writeText("<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../assets/codesite/codesite.css\" />");
+            writeText("<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../assets/codesite/codesearch.css\" />");
+            writeText("<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../assets/codesite/semantic_headers.css\" />");
+            writeText("<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../assets/style.css\" />");
+            writeText("<LINK REL=\"stylesheet\" TYPE=\"text/css\" HREF=\"stylesheet-jdiff.css\" TITLE=\"Style\">");
+	}
+        else {
+            writeText("<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../assets/codesite/codesite.css\" />");
+            writeText("<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../assets/codesite/codesearch.css\" />");
+            writeText("<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../assets/codesite/semantic_headers.css\" />");
+            writeText("<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../assets/style.css\" />");
+            writeText("<LINK REL=\"stylesheet\" TYPE=\"text/css\" HREF=\"../stylesheet-jdiff.css\" TITLE=\"Style\">");
+	}
+// This doesn't work in non-windows browsers, so have to change the stylesheet
+//        writeText("<!-- Override the color choice for the navigation bar -->");
+//        writeText("<STYLE>");
+//        //writeText(".NavBarCell1     { background-color:#FFFF99;} /* palegoldenrod */");
+//        writeText(".NavBarCell1     { background-color:#FFFFCC;} /*  */");
+//        writeText("</STYLE>");
+    }
+
+    /** Write the HTML footer. */
+    public void writeHTMLFooter() {
+    writeText("<script src=\"http://www.google-analytics.com/ga.js\" type=\"text/javascript\">");
+    writeText("</script>");
+    writeText("<script type=\"text/javascript\">");
+    writeText("  try {");
+    writeText("    var pageTracker = _gat._getTracker(\"UA-18071-1\");");
+    writeText("    pageTracker._setAllowAnchor(true);");
+    writeText("    pageTracker._initData();");
+    writeText("    pageTracker._trackPageview();");
+    writeText("  } catch(e) {}");
+    writeText("</script>");
+    writeText("</BODY>");
+    writeText("</HTML>");
+    }
+
+    /** 
+     * Write a section header, which includes a navigation bar. 
+     * 
+     * @param title Title of the header. Contains any links necessary.
+     * @param packageName The name of the current package, with no slashes or 
+     *                    links in it. May be null
+     * @param prevElemLink An HTML link to the previous element (a package or 
+     *                     class). May be null.
+     * @param nextElemLink An HTML link to the next element (a package or 
+     *                     class). May be null.
+     * @param className The name of the current class, with no slashes or 
+     *                  links in it. May be null.
+     * @param level 0 = overview, 1 = package, 2 = class/interface
+     */
+    public void writeSectionHeader(String title, String packageName, 
+                                   String prevElemLink, String nextElemLink,
+                                   String className, int level, 
+                                   boolean hasRemovals, 
+                                   boolean hasAdditions, 
+                                   boolean hasChanges) {
+        writeNavigationBar(packageName, prevElemLink, nextElemLink,
+                           className, level, true,
+                           hasRemovals, hasAdditions, hasChanges);
+        if (level != 0) {
+            reportFile.println("<H2>");
+            reportFile.println(title);
+            reportFile.println("</H2>");
+        }
+    }
+    
+    /** 
+     * Write a section footer, which includes a navigation bar. 
+     * 
+     * @param packageName The name of the current package, with no slashes or 
+     *                    links in it. may be null
+     * @param prevElemLink An HTML link to the previous element (a package or 
+     *                     class). May be null.
+     * @param nextElemLink An HTML link to the next element (a package or 
+     *                     class). May be null.
+     * @param className The name of the current class, with no slashes or 
+     *                  links in it. May be null
+     * @param level 0 = overview, 1 = package, 2 = class/interface
+     */
+    public void writeSectionFooter(String packageName, 
+                                   String prevElemLink, String nextElemLink,
+                                   String className, int level) {
+            writeText("</div><!-- end codesitecontent -->");
+            writeText("<div style=\"padding-left: 10px; padding-right: 10px; margin-top: 0; padding-bottom: 15px;\">");
+            writeText("  <table style=\"width: 100%; border: none;\"><tr>");
+            writeText("    <td style=\"text-align:center;font-size: 10pt; border: none; color: ccc;\"> ");
+            writeText("      <span>&copy;2008 Google - ");
+            writeText("            <a href=\"http://code.google.com\">Code Home</a> - ");
+            writeText("            <a href=\"http://www.google.com/accounts/TOS\">Site Terms of Service</a> - "); 
+            writeText("            <a href=\"http://www.google.com/privacy.html\">Privacy Policy</a> ");
+            writeText("      </span>");
+            writeText("      <div style=\"xborder:1px solid red;position:relative;margin-top:-2em;" );
+            writeText("        font-size:8pt;color:aaa;text-align:right;\">");
+            writeText("        <em>Generated by <a href=\"http://www.jdiff.org/\">JDiff</a></em><br><img ");
+            writeText("        align=\"right\" src=\"../../../assets/jdiff_logo.gif\">");
+            writeText("      </span>");
+            writeText("    </td>");
+            writeText(" </tr></table>");
+            writeText("</div>");
+            writeText("</div><!-- end gc-containter -->");
+/*
+        reportFile.println("<HR>");
+        writeNavigationBar(packageName, prevElemLink, nextElemLink, 
+                           className, level, false,
+                           false, false, false);
+*/
+    }
+   
+    /** 
+     * Write a navigation bar section header. 
+     * 
+     * @param pkgName The name of the current package, with no slashes or 
+     *                links in it.
+     * @param prevElemLink An HTML link to the previous element (a package or 
+     *                     class). May be null.
+     * @param nextElemLink An HTML link to the next element (a package or 
+     *                     class). May be null.
+     * @param className The name of the current class, with no slashes or 
+     *                links in it. May be null.
+     * @param level 0 = overview, 1 = package, 2 = class/interface
+     */
+
+    public void writeNavigationBar(String pkgName,
+                                   String prevElemLink, String nextElemLink,
+                                   String className, int level,
+                                   boolean upperNavigationBar,
+                                   boolean hasRemovals, boolean hasAdditions, 
+                                   boolean hasChanges) {
+
+            String oldAPIName = "Old API";
+            if (apiDiff.oldAPIName_ != null)
+                oldAPIName = apiDiff.oldAPIName_;
+            String newAPIName = "New API";
+            if (apiDiff.newAPIName_ != null)
+                newAPIName = apiDiff.newAPIName_;
+
+            SimpleDateFormat formatter
+              = new SimpleDateFormat ("yyyy.MM.dd HH:mm");
+            Date day = new Date();
+
+	    reportFile.println("<!-- Start of nav bar -->");
+
+	    reportFile.println("<div id=\"gc-container\" style=\"padding-left:1em;padding-right:1em;\" id=\"pagecontent\">");
+	    reportFile.println("<a name=\"top\"></a>");
+	    reportFile.println("<div id=\"gc-header\">");
+	    reportFile.println("  <div id=\"logo\"  style=\"padding-left:1em;\">");
+	    reportFile.println("    <a href=\"../../../documentation.html\" target=\"_top\"><img style=\"border: 0;\" src=\"../../../assets-google/android-logo-sm.gif\" \"/></a>");
+	    reportFile.println("  </div> <!-- End logo -->");
+	    reportFile.println("  <div class=\"and-diff-id\">");
+            reportFile.println("    <table class=\"diffspectable\">");
+	    reportFile.println("      <tr>");
+	    reportFile.println("        <td colspan=\"2\" class=\"diffspechead\">API Diff Specification</td>");
+	    reportFile.println("      </tr>");
+	    reportFile.println("      <tr>");
+	    reportFile.println("        <td class=\"diffspec\" style=\"padding-top:.25em\">To Version:</td>");
+	    reportFile.println("        <td class=\"diffvaluenew\" style=\"padding-top:.25em\">" + newAPIName + "</td>");
+	    reportFile.println("      </tr>");
+	    reportFile.println("      <tr>");
+	    reportFile.println("        <td class=\"diffspec\">From Version:</td>");
+	    reportFile.println("        <td class=\"diffvalueold\">" + oldAPIName + "</td>");
+	    reportFile.println("      </tr>");
+//	    reportFile.println("      <tr>");
+//	    reportFile.println("        <td class=\"diffspec\">Product Type:</td>");
+//	    reportFile.println("        <td class=\"diffvalue\">Generic</td>");
+//	    reportFile.println("      </tr>");
+	    reportFile.println("      <tr>");
+	    reportFile.println("        <td class=\"diffspec\">Generated</td>");
+	    reportFile.println("        <td class=\"diffvalue\">" + formatter.format( day ) + "</td>");
+	    reportFile.println("      </tr>");
+ 	    reportFile.println("    </table>");
+	    reportFile.println("  </div> <!-- End and-diff-id -->");
+
+            if (doStats) {
+	    	reportFile.println("  <div class=\"and-diff-id\">");
+	    	reportFile.println("    <table class=\"diffspectable\">");
+	    	reportFile.println("      <tr>");
+	    	reportFile.println("        <td class=\"diffspec\" colspan=\"2\"><a href=\"jdiff_statistics.html\">Statistics</a></div>");
+	    	reportFile.println("      </tr>");
+ 	    	reportFile.println("    </table>");
+	    	reportFile.println("  </div> <!-- End and-diff-id -->");
+	    }
+
+	    reportFile.println("</div> <!-- End gc-header -->");
+	    reportFile.println("<div id=\"codesiteContent\" style=\"margin-top: 70px;margin-bottom:80px;\">");
+
+/*
+	reportFile.println("<TABLE summary=\"Navigation bar\" BORDER=\"0\" WIDTH=\"100%\" CELLPADDING=\"1\" CELLSPACING=\"0\">");
+        reportFile.println("  <TR>");
+        reportFile.println("    <TD COLSPAN=2 BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\">");
+        reportFile.println("    <TABLE summary=\"Navigation bar\" BORDER=\"0\" CELLPADDING=\"0\" CELLSPACING=\"3\">");
+        reportFile.println("    <TR ALIGN=\"center\" VALIGN=\"top\">");
+        boolean atOverview = (level == 0);
+        boolean atPackage = (level == 1);
+        boolean atClass = (level == 2);
+
+        // Always have a link to the Javadoc files
+        if (atOverview) {
+            reportFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + newDocPrefix + "index.html\" target=\"_top\"><FONT CLASS=\"NavBarFont1\"><B><font size=\"+1\"><tt>" + apiDiff.newAPIName_ + "</tt></font></B></FONT></A>&nbsp;</TD>");
+        } else if (atPackage) {
+            String pkgRef = pkgName;
+            pkgRef = pkgRef.replace('.', '/');
+            pkgRef = newDocPrefix + pkgRef + "/package-summary";
+            reportFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + pkgRef + ".html\" target=\"_top\"><FONT CLASS=\"NavBarFont1\"><B><font size=\"+1\"><tt>" + apiDiff.newAPIName_ + "</tt></font></B></FONT></A>&nbsp;</TD>");
+        } else if (atClass) {
+            String classRef = pkgName + "." + className;
+            classRef = classRef.replace('.', '/');
+            if (className.indexOf('.') != -1) {
+                classRef = pkgName + ".";
+                classRef = classRef.replace('.', '/');
+                classRef = newDocPrefix + classRef + className;
+            } else {
+                classRef = newDocPrefix + classRef;
+            }
+            reportFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + classRef + ".html\" target=\"_top\"><FONT CLASS=\"NavBarFont1\"><B><font size=\"+1\"><tt>" + apiDiff.newAPIName_ + "</tt></font></B></FONT></A>&nbsp;</TD>");
+        }
+
+        if (atOverview) {
+            reportFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1Rev\"> &nbsp;<FONT CLASS=\"NavBarFont1Rev\"><B>Overview</B></FONT>&nbsp;</TD>");
+            reportFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> &nbsp;<FONT CLASS=\"NavBarFont1\">Package</FONT>&nbsp;</TD>");
+            reportFile.println("      <TD BGCOLOR=\"#FFFFFF\" CLASS=\"NavBarCell1\"> &nbsp;<FONT CLASS=\"NavBarFont1\">Class</FONT>&nbsp;</TD>");
+        }
+
+        String changesSummaryName = reportFileName + "-summary" + reportFileExt;
+        if (atPackage) {
+            reportFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + changesSummaryName + "\"><FONT CLASS=\"NavBarFont1\"><B>Overview</B></FONT></A>&nbsp;</TD>");
+            reportFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1Rev\"> &nbsp;<FONT CLASS=\"NavBarFont1Rev\"><B>Package</B></FONT>&nbsp;</TD>");
+            reportFile.println("      <TD BGCOLOR=\"#FFFFFF\" CLASS=\"NavBarCell1\"> &nbsp;<FONT CLASS=\"NavBarFont1\">Class</FONT>&nbsp;</TD>");
+        }
+        if (atClass) {
+            reportFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + changesSummaryName + "\"><FONT CLASS=\"NavBarFont1\"><B>Overview</B></FONT></A>&nbsp;</TD>");
+            reportFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"pkg_" + pkgName + reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Package</B></FONT></A>&nbsp;</TD>");
+            reportFile.println("      <TD BGCOLOR=\"#FFFFFF\" CLASS=\"NavBarCell1Rev\"> &nbsp;<FONT CLASS=\"NavBarFont1Rev\"><B>Class</B></FONT>&nbsp;</TD>");
+        }
+
+        if (!Diff.noDocDiffs) {
+            if (atPackage) {
+                String id = (String)Diff.firstDiffOutput.get(pkgName + "!package");
+                if (id != null)
+                    reportFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + Diff.diffFileName + "index" + reportFileExt  + "#" + id + "\"><FONT CLASS=\"NavBarFont1\"><B>Text Changes</B></FONT></A>&nbsp;</TD>");
+                else
+                    reportFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <FONT CLASS=\"NavBarFont1\">Text Changes</FONT>&nbsp;</TD>");
+            } else if (atClass) {
+                String id = (String)Diff.firstDiffOutput.get(pkgName + "." + className + "!class");
+                if (id != null)
+                    reportFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + Diff.diffFileName + "index" + reportFileExt  + "#" + id + "\"><FONT CLASS=\"NavBarFont1\"><B>Text Changes</B></FONT></A>&nbsp;</TD>");
+                else
+                    reportFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <FONT CLASS=\"NavBarFont1\">Text Changes</FONT>&nbsp;</TD>");
+            } else {
+                reportFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + Diff.diffFileName + "index" + reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Text Changes</B></FONT></A>&nbsp;</TD>");
+            }
+        }
+
+        if (doStats) {
+            reportFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"jdiff_statistics" + reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Statistics</B></FONT></A>&nbsp;</TD>");
+        }
+
+        // Always have a link to the JDiff help file
+        reportFile.println("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"jdiff_help" + reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Help</B></FONT></A>&nbsp;</TD>");
+        reportFile.println("    </TR>");
+        reportFile.println("    </TABLE>");
+        reportFile.println("  </TD>");
+
+        // The right hand side title, only added at the top
+        if (upperNavigationBar) {
+            reportFile.println("  <TD ALIGN=\"right\" VALIGN=\"top\" ROWSPAN=3><EM><b>Generated by<br><a href=\"" + JDiff.jDiffLocation + "\" class=\"staysblack\" target=\"_top\">JDiff</a></b></EM></TD>");
+        } else {
+            reportFile.println("  <TD ALIGN=\"right\" VALIGN=\"top\" ROWSPAN=3></TD>");
+        }
+        reportFile.println("</TR>");
+
+        // Links for frames and no frames
+        reportFile.println("<TR>");
+
+        // All of the previous and next links, and the frames and non-frames 
+        // links are in one table cell
+        reportFile.println("  <TD BGCOLOR=\"" + bgcolor + "\" CLASS=\"NavBarCell2\"><FONT SIZE=\"-2\">");        
+        // Display links to the previous and next packages or classes
+        if (atPackage || atClass) {
+            String elemName = "CLASS";
+            if (className == null) {
+                elemName = "PACKAGE";
+            }
+            if (prevElemLink == null) {
+                reportFile.println("&nbsp;<B>PREV " + elemName + "</B>&nbsp;");
+            } else {
+                reportFile.println("&nbsp;<A HREF=\"" + prevElemLink + "\"><B>PREV " + elemName + "</B></A>");
+            }
+            if (nextElemLink == null) {
+                reportFile.println("&nbsp;<B>NEXT " + elemName + "</B>&nbsp;");
+            } else {
+                reportFile.println("&nbsp;<A HREF=\"" + nextElemLink + "\"><B>NEXT " + elemName + "</B></A>");
+            }
+            reportFile.println("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
+        } else {
+            reportFile.println("  &nbsp;&nbsp;");        
+        }
+        // Links for frames and non-frames.
+        reportFile.println("  <A HREF=\"" + "../" + reportFileName + reportFileExt + "\" TARGET=\"_top\"><B>FRAMES</B></A>  &nbsp;");
+        if (className == null) {
+            if (level == 0) {
+                reportFile.println("  &nbsp;<A HREF=\"" + pkgName + reportFileExt + "\" TARGET=\"_top\"><B>NO FRAMES</B></A></FONT></TD>");
+            } else {
+                reportFile.println("  &nbsp;<A HREF=\"pkg_" + pkgName + reportFileExt + "\" TARGET=\"_top\"><B>NO FRAMES</B></A></FONT></TD>");
+            }
+        } else {
+            reportFile.println("  &nbsp;<A HREF=\"" + pkgName + "." + className + reportFileExt + "\" TARGET=\"_top\"><B>NO FRAMES</B></A></FONT></TD>");
+        }
+
+        // All of the details links are in one table cell
+        if (atClass) {
+            // Links to a class page's sections
+            // The meaning of these three variable is overloaded
+            boolean hasCtors = hasRemovals; 
+            boolean hasMethods = hasAdditions; 
+            boolean hasFields = hasChanges; 
+            if (hasCtors || hasMethods || hasFields) {
+                reportFile.println("  <TD BGCOLOR=\"" + bgcolor + "\" CLASS=\"NavBarCell3\"><FONT SIZE=\"-2\"> DETAIL: &nbsp;");
+                if (hasCtors) {
+                    reportFile.println("<a href=\"#constructors\">CONSTRUCTORS</a>&nbsp;|&nbsp;");
+                } else {
+                    reportFile.println("CONSTRUCTORS&nbsp;|&nbsp;");
+                }
+                if (hasMethods) {
+                    reportFile.println("<a href=\"#methods\">METHODS</a>&nbsp;|&nbsp;");
+                } else {
+                    reportFile.println("METHODS&nbsp;|&nbsp;");
+                }
+                if (hasFields) {
+                    reportFile.println("<a href=\"#fields\">FIELDS</a>");
+                } else {
+                    reportFile.println("FIELDS");
+                }
+                reportFile.println("  </FONT></TD>");
+            } else {
+                // Make the end of the table line match the length of the top
+                reportFile.println("<TD BGCOLOR=\"0xFFFFFF\" CLASS=\"NavBarCell3\"></TD>"); 
+            }
+        } else {
+            // Links to a package page's sections
+            if (hasRemovals || hasAdditions || hasChanges) {
+                reportFile.println("  <TD BGCOLOR=\"" + bgcolor + "\" CLASS=\"NavBarCell3\"><FONT SIZE=\"-2\"> DETAIL: &nbsp;");
+                if (hasRemovals) {
+                    reportFile.println("<a href=\"#Removed\">REMOVED</a>&nbsp;|&nbsp;");
+                } else {
+                    reportFile.println("REMOVED&nbsp;|&nbsp;");
+                }
+                if (hasAdditions) {
+                    reportFile.println("<a href=\"#Added\">ADDED</a>&nbsp;|&nbsp;");
+                } else {
+                    reportFile.println("ADDED&nbsp;|&nbsp;");
+                }
+                if (hasChanges) {
+                    reportFile.println("<a href=\"#Changed\">CHANGED</a>");
+                } else {
+                    reportFile.println("CHANGED");
+                }
+                reportFile.println("  </FONT></TD>");
+            } else {
+                // Make the end of the table line match the length of the top
+                reportFile.println("<TD BGCOLOR=\"0xFFFFFF\" CLASS=\"NavBarCell3\"></TD>"); 
+            }
+        }
+
+        reportFile.println("</TR>");
+        reportFile.println("</TABLE>");
+        reportFile.println("<HR>");
+        reportFile.println("<!-- End of nav bar -->");
+*/
+    }
+    
+    /** Write the start of a table. */
+    public void writeTableStart(String title, int colSpan) {
+        reportFile.println("<p>");
+        // Assumes that the first word of the title categorizes the table type
+        // and that there is a space after the first word in the title
+        int idx = title.indexOf(' ');
+        String namedAnchor = title.substring(0, idx);
+        reportFile.println("<a NAME=\"" + namedAnchor + "\"></a>"); // Named anchor
+        reportFile.println("<TABLE summary=\"" + title+ "\" WIDTH=\"100%\">");
+        reportFile.println("<TR>");
+        reportFile.print("  <TH VALIGN=\"TOP\" COLSPAN=" + colSpan + ">");
+        reportFile.println(title + "</FONT></TD>");
+        reportFile.println("</TH>");
+    }
+
+    /** 
+     * If a class or package name is considered to be too long for convenient
+     * display, insert <br> in the middle of it at a period.
+     */
+    public String makeTwoRows(String name) {
+        if (name.length() < 30)
+            return name;
+        int idx = name.indexOf(".", 20);
+        if (idx == -1)
+            return name;
+        int len = name.length();
+        String res = name.substring(0, idx+1) + "<br>" + name.substring(idx+1, len);
+        return res;
+    }
+
+    /** 
+     * Write a table entry for a package, with support for links to Javadoc 
+     * for removed packages. 
+     *
+     * linkType: 0 - no link by default, 1 = link to Javadoc HTML file, 2 = link to JDiff file
+     */
+    public void writePackageTableEntry(String pkgName, int linkType, 
+                                       String possibleComment, boolean useOld) {
+        if (!useOld) {
+            reportFile.println("<TR BGCOLOR=\"" + bgcolor + "\" CLASS=\"TableRowColor\">");
+            reportFile.println("  <TD VALIGN=\"TOP\" WIDTH=\"25%\">");
+            reportFile.println("  <A NAME=\"" + pkgName + "\"></A>"); // Named anchor
+        }
+        //String shownPkgName = makeTwoRows(pkgName);
+        if (linkType == 0) {
+            if (oldDocPrefix == null) {
+                // No link
+                reportFile.print("  " + pkgName);
+            } else {
+                // Call this method again but this time to emit a link to the 
+                // old program element.
+                writePackageTableEntry(pkgName, 1, possibleComment, true);
+            }
+        } else if (linkType == 1) {
+            // Link to HTML file for the package
+            String pkgRef = pkgName;
+            pkgRef = pkgRef.replace('.', '/');
+            if (useOld)
+                pkgRef = oldDocPrefix + pkgRef + "/package-summary";
+            else
+                pkgRef = newDocPrefix + pkgRef + "/package-summary";
+            reportFile.println("  <nobr><A HREF=\"" + pkgRef + ".html\" target=\"_top\"><font size=\"+1\"><tt>" + pkgName + "</tt></font></A></nobr>");
+        } else if (linkType == 2) {
+            reportFile.println("  <nobr><A HREF=\"pkg_" + pkgName + reportFileExt + "\">" + pkgName + "</A></nobr>");
+        } 
+        if (!useOld) {
+            reportFile.println("  </TD>");
+            emitComment(pkgName, possibleComment, linkType);
+            reportFile.println("</TR>");
+        }
+    }
+
+    /** 
+     * Write a table entry for a class or interface. 
+     *
+     * linkType: 0 - no link by default, 1 = link to Javadoc HTML file, 2 = link to JDiff file
+     */
+    public void writeClassTableEntry(String pkgName, String className, 
+                                     int linkType, boolean isInterface, 
+                                     String possibleComment, boolean useOld) {
+        if (!useOld) {
+            reportFile.println("<TR BGCOLOR=\"" + bgcolor + "\" CLASS=\"TableRowColor\">");
+            reportFile.println("  <TD VALIGN=\"TOP\" WIDTH=\"25%\">");
+            reportFile.println("  <A NAME=\"" + className + "\"></A>"); // Named anchor
+        }
+        String fqName = pkgName + "." + className;
+        String shownClassName = makeTwoRows(className);
+        if (linkType == 0) {
+            if (oldDocPrefix == null) {
+                // No link
+                if (isInterface)
+                    reportFile.println("  <I>" + shownClassName + "</I>");
+                else
+                    reportFile.println("  " + shownClassName);
+            } else {
+                writeClassTableEntry(pkgName, className, 
+                                     1, isInterface, 
+                                     possibleComment, true);
+            }
+        } else if (linkType == 1) {
+            // Link to HTML file for the class
+            String classRef = fqName;
+            // Deal with inner classes
+            if (className.indexOf('.') != -1) {
+                classRef = pkgName + ".";
+                classRef = classRef.replace('.', '/');
+                if (useOld)
+                    classRef = oldDocPrefix + classRef + className;
+                else
+                    classRef = newDocPrefix + classRef + className;
+            } else {
+                classRef = classRef.replace('.', '/');
+                if (useOld)
+                    classRef = oldDocPrefix + classRef;
+                else
+                    classRef = newDocPrefix + classRef;
+            }
+            reportFile.print("  <nobr><A HREF=\"" + classRef + ".html\" target=\"_top\"><font size=\"+1\"><tt>");
+            if (isInterface)
+                reportFile.print("<I>" + shownClassName + "</I>");
+            else
+                reportFile.print(shownClassName);
+            reportFile.println("</tt></font></A></nobr>");
+        } else if (linkType == 2) {
+            reportFile.print("  <nobr><A HREF=\"" + fqName + reportFileExt + "\">");
+            if (isInterface)
+                reportFile.print("<I>" + shownClassName + "</I>");
+            else
+                reportFile.print(shownClassName);
+            reportFile.println("</A></nobr>");
+        } 
+        if (!useOld) {
+            reportFile.println("  </TD>");
+            emitComment(fqName, possibleComment, linkType);
+            reportFile.println("</TR>");
+        }
+    }
+
+    /** 
+     * Write a table entry for a constructor. 
+     *
+     * linkType: 0 - no link by default, 1 = link to Javadoc HTML file
+     */
+    public void writeCtorTableEntry(String pkgName, String className, 
+                                    String type, int linkType, 
+                                    String possibleComment, boolean useOld) {
+        String fqName = pkgName + "." + className;
+        String shownClassName = makeTwoRows(className);
+        String lt = "removed";
+        if (linkType ==1)
+            lt = "added";
+        String commentID = fqName + ".ctor_" + lt + "(" + type + ")";
+        if (!useOld) {
+            reportFile.println("<TR BGCOLOR=\"" + bgcolor + "\" CLASS=\"TableRowColor\">");
+            reportFile.println("  <TD VALIGN=\"TOP\" WIDTH=\"25%\">");
+            reportFile.println("  <A NAME=\"" + commentID + "\"></A>"); // Named anchor
+        }
+        String shortType = simpleName(type);
+        if (linkType == 0) {
+            if (oldDocPrefix == null) {
+                // No link
+                reportFile.print("  <nobr>" + pkgName);
+                emitTypeWithParens(shortType);
+                reportFile.println("</nobr>");
+            } else {
+                writeCtorTableEntry(pkgName, className, 
+                                    type, 1, 
+                                    possibleComment, true);
+            }
+        } else if (linkType == 1) {
+            // Link to HTML file for the package
+            String memberRef = fqName.replace('.', '/');
+            // Deal with inner classes
+            if (className.indexOf('.') != -1) {
+                memberRef = pkgName + ".";
+                memberRef = memberRef.replace('.', '/');
+                if (useOld) {
+                    // oldDocPrefix is non-null at this point
+                    memberRef = oldDocPrefix + memberRef + className;
+                } else {
+                    memberRef = newDocPrefix + memberRef + className;
+                }
+            } else {
+                if (useOld) {
+                    // oldDocPrefix is non-null at this point
+                    memberRef = oldDocPrefix + memberRef;
+                } else {
+                    memberRef = newDocPrefix + memberRef;
+                }
+            }
+            reportFile.print("  <nobr><A HREF=\"" + memberRef + ".html#" + className +
+                             "(" + type + ")\" target=\"_top\"><font size=\"+1\"><tt>" + shownClassName + "</tt></font></A>");
+            emitTypeWithParens(shortType);
+            reportFile.println("</nobr>");
+        }
+        if (!useOld) {
+            reportFile.println("  </TD>");
+            emitComment(commentID, possibleComment, linkType);
+            reportFile.println("</TR>");
+        }
+    }
+
+    /** 
+     * Write a table entry for a changed constructor.
+     */
+    public void writeCtorChangedTableEntry(String pkgName, String className, 
+                                           MemberDiff memberDiff) {
+        String fqName = pkgName + "." + className;
+        String newSignature = memberDiff.newType_;
+        if (newSignature.compareTo("void") == 0)
+            newSignature = "";
+        String commentID = fqName + ".ctor_changed(" + newSignature + ")";
+        reportFile.println("<TR BGCOLOR=\"" + bgcolor + "\" CLASS=\"TableRowColor\">");
+        reportFile.println("  <TD VALIGN=\"TOP\" WIDTH=\"25%\">");
+        reportFile.println("  <A NAME=\"" + commentID + "\"></A>"); // Named anchor
+        String memberRef = fqName.replace('.', '/');            
+        String shownClassName = makeTwoRows(className);
+        // Deal with inner classes
+        if (className.indexOf('.') != -1) {
+            memberRef = pkgName + ".";
+            memberRef = memberRef.replace('.', '/');
+            memberRef = newDocPrefix + memberRef + className;
+        } else {
+            memberRef = newDocPrefix + memberRef;
+        }
+        String newType = memberDiff.newType_;
+        if (newType.compareTo("void") == 0)
+            newType = "";
+        String shortNewType = simpleName(memberDiff.newType_);
+        // Constructors have the linked name, then the type in parentheses.
+        reportFile.print("  <nobr><A HREF=\"" + memberRef + ".html#" + className + "(" + newType + ")\" target=\"_top\"><font size=\"+1\"><tt>");
+        reportFile.print(shownClassName);
+        reportFile.print("</tt></font></A>");
+        emitTypeWithParens(shortNewType);
+        reportFile.println("  </nobr>");
+        reportFile.println("  </TD>");
+        
+        // Report changes in documentation
+        if (reportDocChanges && memberDiff.documentationChange_ != null) {
+            String oldMemberRef = null;
+            String oldType = null;
+            if (oldDocPrefix != null) {
+                oldMemberRef = pkgName + "." + className;
+                oldMemberRef = oldMemberRef.replace('.', '/');
+                if (className.indexOf('.') != -1) {
+                    oldMemberRef = pkgName + ".";
+                    oldMemberRef = oldMemberRef.replace('.', '/');
+                    oldMemberRef = oldDocPrefix + oldMemberRef + className;
+                } else {
+                    oldMemberRef = oldDocPrefix + oldMemberRef;
+                }
+                oldType = memberDiff.oldType_;
+                if (oldType.compareTo("void") == 0)
+                    oldType = "";
+            }
+            if (oldDocPrefix != null) 
+                memberDiff.documentationChange_ += "<A HREF=\"" + 
+                    oldMemberRef + ".html#" + className + "(" + oldType + 
+                    ")\" target=\"_self\"><font size=\"+1\"><tt>old</tt></font></A> to ";
+            else 
+                memberDiff.documentationChange_ += "<font size=\"+1\"><tt>old</tt></font> to ";
+            memberDiff.documentationChange_ += "<A HREF=\"" + memberRef + 
+                ".html#" + className + "(" + newType + 
+                ")\" target=\"_self\"><font size=\"+1\"><tt>new</tt></font></A>.<br>";
+        }
+
+        emitChanges(memberDiff, 0);
+        emitComment(commentID, null, 2);
+
+        reportFile.println("</TR>");
+    }
+
+    /** 
+     * Write a table entry for a method. 
+     *
+     * linkType: 0 - no link by default, 1 = link to Javadoc HTML file
+     */
+    public void writeMethodTableEntry(String pkgName, String className, 
+                                      MethodAPI methodAPI, int linkType, 
+                                      String possibleComment, boolean useOld) {
+        String fqName = pkgName + "." + className;
+        String signature = methodAPI.getSignature(); 
+        String methodName = methodAPI.name_;
+        String lt = "removed";
+        if (linkType ==1)
+            lt = "added";
+        String commentID = fqName + "." + methodName + "_" + lt + "(" + signature + ")";
+        if (!useOld) {
+            reportFile.println("<TR BGCOLOR=\"" + bgcolor + "\" CLASS=\"TableRowColor\">");
+            reportFile.println("  <TD VALIGN=\"TOP\" WIDTH=\"25%\">");
+            reportFile.println("  <A NAME=\"" + commentID + "\"></A>"); // Named anchor
+        }
+        if (signature.compareTo("void") == 0)
+            signature = "";
+        String shortSignature = simpleName(signature);
+        String returnType = methodAPI.returnType_;
+        String shortReturnType = simpleName(returnType);
+        if (linkType == 0) {
+            if (oldDocPrefix == null) {
+                // No link
+                reportFile.print("  <nobr>");
+                emitType(shortReturnType);
+                reportFile.print("&nbsp;" + methodName);
+                emitTypeWithParens(shortSignature);
+                reportFile.println("</nobr>");
+            } else {
+                writeMethodTableEntry(pkgName, className, 
+                                      methodAPI, 1, 
+                                      possibleComment, true);
+            }
+        } else if (linkType == 1) {
+            // Link to HTML file for the package
+            String memberRef = fqName.replace('.', '/');
+            // Deal with inner classes
+            if (className.indexOf('.') != -1) {
+                memberRef = pkgName + ".";
+                memberRef = memberRef.replace('.', '/');
+                if (useOld) {
+                    // oldDocPrefix is non-null at this point
+                    memberRef = oldDocPrefix + memberRef + className;
+                } else {
+                    memberRef = newDocPrefix + memberRef + className;
+                }
+            } else {
+                if (useOld) {
+                    // oldDocPrefix is non-null at this point
+                    memberRef = oldDocPrefix + memberRef;
+                } else {
+                    memberRef = newDocPrefix + memberRef;
+                }
+            }
+            reportFile.print("  <nobr>");
+            emitType(shortReturnType);
+            reportFile.print("&nbsp;<A HREF=\"" + memberRef + ".html#" + methodName +
+               "(" + signature + ")\" target=\"_top\"><font size=\"+1\"><tt>" + methodName + "</tt></font></A>");
+            emitTypeWithParens(shortSignature);
+            reportFile.println("</nobr>");
+        }
+        if (!useOld) {
+            reportFile.println("  </TD>");
+            emitComment(commentID, possibleComment, linkType);
+            reportFile.println("</TR>");
+        }
+    }
+
+    /**
+     * Write a table entry for a changed method.
+     */
+    public void writeMethodChangedTableEntry(String pkgName, String className, 
+                                      MemberDiff memberDiff) {
+        String memberName = memberDiff.name_;
+        // Generally nowhere to break a member name anyway
+        // String shownMemberName = makeTwoRows(memberName);
+        String fqName = pkgName + "." + className;
+        String newSignature = memberDiff.newSignature_;
+        String commentID = fqName + "." + memberName + "_changed(" + newSignature + ")";
+        reportFile.println("<TR BGCOLOR=\"" + bgcolor + "\" CLASS=\"TableRowColor\">");
+
+        reportFile.println("  <TD VALIGN=\"TOP\" WIDTH=\"25%\">");
+        reportFile.println("  <A NAME=\"" + commentID + "\"></A>"); // Named anchor
+        String memberRef = fqName.replace('.', '/');            
+        // Deal with inner classes
+        if (className.indexOf('.') != -1) {
+            memberRef = pkgName + ".";
+            memberRef = memberRef.replace('.', '/');
+            memberRef = newDocPrefix + memberRef + className;
+        } else {
+            memberRef = newDocPrefix + memberRef;
+        }
+        // Javadoc generated HTML has no named anchors for methods
+        // inherited from other classes, so link to the defining class' method.
+        // Only copes with non-inner classes.
+        if (className.indexOf('.') == -1 &&
+            memberDiff.modifiersChange_ != null &&
+            memberDiff.modifiersChange_.indexOf("but is now inherited from") != -1) {
+            memberRef = memberDiff.inheritedFrom_;
+            memberRef = memberRef.replace('.', '/'); 
+            memberRef = newDocPrefix + memberRef;
+        }
+        
+        String newReturnType = memberDiff.newType_;
+        String shortReturnType = simpleName(newReturnType); 
+        String shortSignature = simpleName(newSignature);        
+        reportFile.print("  <nobr>");
+        emitTypeWithNoParens(shortReturnType); 
+        reportFile.print("&nbsp;<A HREF=\"" + memberRef + ".html#" + 
+                         memberName + "(" + newSignature + ")\" target=\"_top\"><font size=\"+1\"><tt>");
+        reportFile.print(memberName);
+        reportFile.print("</tt></font></A>");
+        emitTypeWithParens(shortSignature);
+        reportFile.println("  </nobr>");
+        reportFile.println("  </TD>");
+        
+        // Report changes in documentation
+        if (reportDocChanges && memberDiff.documentationChange_ != null) {
+            String oldMemberRef = null;
+            String oldSignature = null;
+            if (oldDocPrefix != null) {
+                oldMemberRef = pkgName + "." + className;
+                oldMemberRef = oldMemberRef.replace('.', '/');
+                if (className.indexOf('.') != -1) {
+                    oldMemberRef = pkgName + ".";
+                    oldMemberRef = oldMemberRef.replace('.', '/');
+                    oldMemberRef = oldDocPrefix + oldMemberRef + className;
+                } else {
+                    oldMemberRef = oldDocPrefix + oldMemberRef;
+                }
+                oldSignature = memberDiff.oldSignature_;
+            }
+            if (oldDocPrefix != null) 
+                memberDiff.documentationChange_ += "<A HREF=\"" + 
+                    oldMemberRef + ".html#" + memberName + "(" + 
+                    oldSignature + ")\" target=\"_self\"><font size=\"+1\"><tt>old</tt></font></A> to ";
+            else
+                memberDiff.documentationChange_ += "<font size=\"+1\"><tt>old</tt></font> to ";
+            memberDiff.documentationChange_ += "<A HREF=\"" + memberRef + 
+                ".html#" + memberName + "(" + newSignature + 
+                ")\" target=\"_self\"><font size=\"+1\"><tt>new</tt></font></A>.<br>";
+        }
+
+        emitChanges(memberDiff, 1);
+        // Get the comment from the parent class if more appropriate
+        if (memberDiff.modifiersChange_ != null) {
+            int parentIdx = memberDiff.modifiersChange_.indexOf("now inherited from");
+            if (parentIdx != -1) {
+                // Change the commentID to pick up the appropriate method
+                commentID = memberDiff.inheritedFrom_ + "." + memberName + 
+                    "_changed(" + newSignature + ")";
+            }
+        }
+        emitComment(commentID, null, 2);
+        
+        reportFile.println("</TR>");
+    }
+
+    /** 
+     * Write a table entry for a field. 
+     *
+     * linkType: 0 - no link by default, 1 = link to Javadoc HTML file
+     */
+    public void writeFieldTableEntry(String pkgName, String className, 
+                                     FieldAPI fieldAPI, int linkType, 
+                                     String possibleComment, boolean useOld) {
+        String fqName = pkgName + "." + className;
+        // Fields can only appear in one table, so no need to specify _added etc
+        String fieldName = fieldAPI.name_;
+        // Generally nowhere to break a member name anyway
+        // String shownFieldName = makeTwoRows(fieldName);
+        String commentID = fqName + "." + fieldName;
+        if (!useOld) {
+            reportFile.println("<TR BGCOLOR=\"" + bgcolor + "\" CLASS=\"TableRowColor\">");
+            reportFile.println("  <TD VALIGN=\"TOP\" WIDTH=\"25%\">");
+            reportFile.println("  <A NAME=\"" + commentID + "\"></A>"); // Named anchor
+        }
+        String fieldType = fieldAPI.type_;
+        if (fieldType.compareTo("void") == 0)
+            fieldType = "";
+        String shortFieldType = simpleName(fieldType);
+        if (linkType == 0) {
+            if (oldDocPrefix == null) {
+                // No link.
+                reportFile.print("  ");
+                emitType(shortFieldType);
+                reportFile.println("&nbsp;" + fieldName);
+            } else {
+                writeFieldTableEntry(pkgName, className, 
+                                     fieldAPI, 1, 
+                                     possibleComment, true);
+            }
+        } else if (linkType == 1) {
+            // Link to HTML file for the package.
+            String memberRef = fqName.replace('.', '/');
+            // Deal with inner classes
+            if (className.indexOf('.') != -1) {
+                memberRef = pkgName + ".";
+                memberRef = memberRef.replace('.', '/');
+                if (useOld)
+                    memberRef = oldDocPrefix + memberRef + className;
+                else
+                    memberRef = newDocPrefix + memberRef + className;
+            } else {
+                if (useOld)
+                    memberRef = oldDocPrefix + memberRef;
+                else
+                    memberRef = newDocPrefix + memberRef;
+            }
+            reportFile.print("  <nobr>");
+            emitType(shortFieldType);
+            reportFile.println("&nbsp;<A HREF=\"" + memberRef + ".html#" + fieldName +
+               "\" target=\"_top\"><font size=\"+1\"><tt>" + fieldName + "</tt></font></A></nobr>");
+        }
+        if (!useOld) {
+            reportFile.println("  </TD>");
+            emitComment(commentID, possibleComment, linkType);
+            reportFile.println("</TR>");
+        }
+        }
+
+    /** 
+     * Write a table entry for a changed field.
+     */
+    public void writeFieldChangedTableEntry(String pkgName, String className, 
+                                            MemberDiff memberDiff) {
+        String memberName = memberDiff.name_;
+        // Generally nowhere to break a member name anyway
+        // String shownMemberName = makeTwoRows(memberName);
+        String fqName = pkgName + "." + className;
+        // Fields have unique names in a class
+        String commentID = fqName + "." + memberName;
+        reportFile.println("<TR BGCOLOR=\"" + bgcolor + "\" CLASS=\"TableRowColor\">");
+
+        reportFile.println("  <TD VALIGN=\"TOP\" WIDTH=\"25%\">");
+        reportFile.println("  <A NAME=\"" + commentID + "\"></A>"); // Named anchor
+        String memberRef = fqName.replace('.', '/');            
+        // Deal with inner classes
+        if (className.indexOf('.') != -1) {
+            memberRef = pkgName + ".";
+            memberRef = memberRef.replace('.', '/');
+            memberRef = newDocPrefix + memberRef + className;
+        } else {
+            memberRef = newDocPrefix + memberRef;
+        }
+        // Javadoc generated HTML has no named anchors for fields
+        // inherited from other classes, so link to the defining class' field.
+        // Only copes with non-inner classes.
+        if (className.indexOf('.') == -1 &&
+            memberDiff.modifiersChange_ != null &&
+            memberDiff.modifiersChange_.indexOf("but is now inherited from") != -1) {
+            memberRef = memberDiff.inheritedFrom_;
+            memberRef = memberRef.replace('.', '/'); 
+            memberRef = newDocPrefix + memberRef;
+        }
+
+        String newType = memberDiff.newType_;
+        String shortNewType = simpleName(newType); 
+        reportFile.print("  <nobr>");
+        emitTypeWithNoParens(shortNewType);
+        reportFile.print("&nbsp;<A HREF=\"" + memberRef + ".html#" + 
+                         memberName + "\" target=\"_top\"><font size=\"+1\"><tt>");
+        reportFile.print(memberName);
+        reportFile.print("</tt></font></A></nobr>");
+        reportFile.println("  </TD>");
+        
+        // Report changes in documentation
+        if (reportDocChanges && memberDiff.documentationChange_ != null) {
+            String oldMemberRef = null;
+            if (oldDocPrefix != null) {
+                oldMemberRef = pkgName + "." + className;
+                oldMemberRef = oldMemberRef.replace('.', '/');
+                if (className.indexOf('.') != -1) {
+                    oldMemberRef = pkgName + ".";
+                    oldMemberRef = oldMemberRef.replace('.', '/');
+                    oldMemberRef = oldDocPrefix + oldMemberRef + className;
+                } else {
+                    oldMemberRef = oldDocPrefix + oldMemberRef;
+                }
+            }
+            if (oldDocPrefix != null) 
+                memberDiff.documentationChange_ += "<A HREF=\"" + 
+                    oldMemberRef + ".html#" + memberName + "\" target=\"_self\"><font size=\"+1\"><tt>old</tt></font></A> to ";
+            else
+                memberDiff.documentationChange_ += "<font size=\"+1\"><tt>old</tt></font> to ";
+            memberDiff.documentationChange_ += "<A HREF=\"" + memberRef + 
+                ".html#" + memberName + "\" target=\"_self\"><font size=\"+1\"><tt>new</tt></font></A>.<br>";
+        }
+
+        emitChanges(memberDiff, 2);
+        // Get the comment from the parent class if more appropriate
+        if (memberDiff.modifiersChange_ != null) {
+            int parentIdx = memberDiff.modifiersChange_.indexOf("now inherited from");
+            if (parentIdx != -1) {
+                // Change the commentID to pick up the appropriate method
+                commentID = memberDiff.inheritedFrom_ + "." + memberName;
+            }
+        }
+        emitComment(commentID, null, 2);
+        
+        reportFile.println("</TR>");
+    }
+
+    /**
+     * Emit all changes associated with a MemberDiff as an entry in a table.
+     *
+     * @param memberType 0 = ctor, 1 = method, 2 = field
+     */
+    public void emitChanges(MemberDiff memberDiff, int memberType){
+        reportFile.println("  <TD VALIGN=\"TOP\" WIDTH=\"30%\">");
+        boolean hasContent = false;
+        // The type or return type changed
+        if (memberDiff.oldType_.compareTo(memberDiff.newType_) != 0) {
+            String shortOldType = simpleName(memberDiff.oldType_);
+            String shortNewType = simpleName(memberDiff.newType_);
+            if (memberType == 1) {
+                reportFile.print("Change in return type from ");
+            } else {
+                reportFile.print("Change in type from ");
+            }
+            if (shortOldType.compareTo(shortNewType) == 0) {
+                // The types differ in package name, so use the full name
+                shortOldType = memberDiff.oldType_;
+                shortNewType = memberDiff.newType_;
+            }
+            emitType(shortOldType);
+            reportFile.print(" to ");
+            emitType(shortNewType);
+            reportFile.println(".<br>");
+            hasContent = true;
+        }
+        // The signatures changed - only used by methods
+        if (memberType == 1 &&
+            memberDiff.oldSignature_ != null && 
+            memberDiff.newSignature_ != null && 
+            memberDiff.oldSignature_.compareTo(memberDiff.newSignature_) != 0) {
+            String shortOldSignature = simpleName(memberDiff.oldSignature_);
+            String shortNewSignature = simpleName(memberDiff.newSignature_);
+            if (shortOldSignature.compareTo(shortNewSignature) == 0) {
+                // The signatures differ in package names, so use the full form
+                shortOldSignature = memberDiff.oldSignature_;
+                shortNewSignature = memberDiff.newSignature_;
+            }
+            if (hasContent)
+                reportFile.print(" "); 
+            reportFile.print("Change in signature from ");
+            if (shortOldSignature.compareTo("") == 0)
+                shortOldSignature = "void";
+            emitType(shortOldSignature);
+            reportFile.print(" to ");
+            if (shortNewSignature.compareTo("") == 0)
+                shortNewSignature = "void";
+            emitType(shortNewSignature);
+            reportFile.println(".<br>");
+            hasContent = true;
+        }
+        // The exceptions are only non-null in methods and constructors
+        if (memberType != 2 &&
+            memberDiff.oldExceptions_ != null && 
+            memberDiff.newExceptions_ != null && 
+            memberDiff.oldExceptions_.compareTo(memberDiff.newExceptions_) != 0) {
+            if (hasContent)
+                reportFile.print(" "); 
+            // If either one of the exceptions has no spaces in it, or is 
+            // equal to "no exceptions", then just display the whole 
+            // exceptions texts.
+            int spaceInOld = memberDiff.oldExceptions_.indexOf(" ");
+            if (memberDiff.oldExceptions_.compareTo("no exceptions") == 0)
+                spaceInOld = -1;
+            int spaceInNew = memberDiff.newExceptions_.indexOf(" ");
+            if (memberDiff.newExceptions_.compareTo("no exceptions") == 0)
+                spaceInNew = -1;
+            if (spaceInOld == -1 || spaceInNew == -1) {
+                reportFile.print("Change in exceptions thrown from ");
+                emitException(memberDiff.oldExceptions_); 
+                reportFile.print(" to " );
+                emitException(memberDiff.newExceptions_); 
+                reportFile.println(".<br>");
+            } else {
+                // Too many exceptions become unreadable, so just show the 
+                // individual changes. Catch the case where exceptions are
+                // just reordered.
+                boolean firstChange = true;
+                int numRemoved = 0;
+                StringTokenizer stOld = new StringTokenizer(memberDiff.oldExceptions_, ", ");
+                while (stOld.hasMoreTokens()) {
+                    String oldException = stOld.nextToken();
+                    if (!memberDiff.newExceptions_.startsWith(oldException) &&
+                        !(memberDiff.newExceptions_.indexOf(", " + oldException) != -1)) {
+                        if (firstChange) {
+                            reportFile.print("Change in exceptions: ");
+                            firstChange = false;
+                        }
+                        if (numRemoved != 0)
+                            reportFile.print(", ");
+                        emitException(oldException);
+                        numRemoved++;
+                    }
+                }
+                if (numRemoved == 1)
+                    reportFile.print(" was removed.");
+                else if (numRemoved > 1)
+                    reportFile.print(" were removed.");
+                
+                int numAdded = 0;
+                StringTokenizer stNew = new StringTokenizer(memberDiff.newExceptions_, ", ");
+                while (stNew.hasMoreTokens()) {
+                    String newException = stNew.nextToken();
+                    if (!memberDiff.oldExceptions_.startsWith(newException) &&
+                        !(memberDiff.oldExceptions_.indexOf(", " + newException) != -1)) {
+                        if (firstChange) {
+                            reportFile.print("Change in exceptions: ");
+                            firstChange = false;
+                        }
+                        if (numAdded != 0)
+                            reportFile.println(", ");    
+                        else
+                            reportFile.println(" ");
+                        emitException(newException);
+                        numAdded++;
+                    }
+                }
+                if (numAdded == 1)
+                    reportFile.print(" was added");
+                else if (numAdded > 1)
+                    reportFile.print(" were added");
+                else if (numAdded == 0 && numRemoved == 0 && firstChange)
+                    reportFile.print("Exceptions were reordered");
+                reportFile.println(".<br>");
+            }
+            // Note the changes between a comma-separated list of Strings
+            hasContent = true;
+        }
+
+        if (memberDiff.documentationChange_ != null) {
+            if (hasContent)
+                reportFile.print(" "); 
+            reportFile.print(memberDiff.documentationChange_);
+            hasContent = true;
+        }
+            
+        // Last, so no need for a <br>
+        if (memberDiff.modifiersChange_ != null) {
+            if (hasContent)
+                reportFile.print(" "); 
+            reportFile.println(memberDiff.modifiersChange_);
+            hasContent = true;
+        }
+        reportFile.println("  </TD>");
+    }
+
+    /** 
+     * Emit a string which is an exception by surrounding it with 
+     * &lt;code&gt; tags.
+     * If there is a space in the type, e.g. &quot;String, File&quot;, then
+     * surround it with parentheses too. Do not add &lt;code&gt; tags or 
+     * parentheses if the String is "no exceptions".
+     */
+    public void emitException(String ex) {
+        if (ex.compareTo("no exceptions") == 0) {
+            reportFile.print(ex);
+        } else {
+            if (ex.indexOf(' ') != -1) {
+                reportFile.print("(<code>" + ex + "</code>)");
+            } else {
+                reportFile.print("<code>" + ex + "</code>");
+            }
+        }
+    }
+
+    /** 
+     * Emit a string which is a type by surrounding it with &lt;code&gt; tags.
+     * If there is a space in the type, e.g. &quot;String, File&quot;, then
+     * surround it with parentheses too.
+     */
+    public void emitType(String type) {
+        if (type.compareTo("") == 0)
+            return;
+        if (type.indexOf(' ') != -1) {
+            reportFile.print("(<code>" + type + "</code>)");
+        } else {
+            reportFile.print("<code>" + type + "</code>");
+        }
+    }
+
+    /** 
+     * Emit a string which is a type by surrounding it with &lt;code&gt; tags.
+     * Also surround it with parentheses too. Used to display methods' 
+     * parameters.
+     * Suggestions for where a browser should break the 
+     * text are provided with &lt;br> and &ltnobr> tags.
+     */
+    public static void emitTypeWithParens(String type) {
+        emitTypeWithParens(type, true);
+    }
+
+    /** 
+     * Emit a string which is a type by surrounding it with &lt;code&gt; tags.
+     * Also surround it with parentheses too. Used to display methods' 
+     * parameters.
+     */
+    public static void emitTypeWithParens(String type, boolean addBreaks) {
+        if (type.compareTo("") == 0)
+            reportFile.print("()");
+        else {
+            int idx = type.indexOf(", ");
+            if (!addBreaks || idx == -1) {
+                reportFile.print("(<code>" + type + "</code>)");
+            } else {
+                // Make the browser break text at reasonable places
+                String sepType = null;
+                StringTokenizer st = new StringTokenizer(type, ", ");
+                while (st.hasMoreTokens()) {
+                    String p = st.nextToken();
+                    if (sepType == null)
+                        sepType = p;
+                    else
+                        sepType += ",</nobr> " + p + "<nobr>";                        
+                }
+                reportFile.print("(<code>" + sepType + "<nobr></code>)");
+            }
+        }
+    }
+
+    /** 
+     * Emit a string which is a type by surrounding it with &lt;code&gt; tags.
+     * Do not surround it with parentheses. Used to display methods' return
+     * types and field types.
+     */
+    public static void emitTypeWithNoParens(String type) {
+        if (type.compareTo("") != 0)
+            reportFile.print("<code>" + type + "</code>");
+    }
+
+    /** 
+     * Return a String with the simple names of the classes in fqName.
+     * &quot;java.lang.String&quot; becomes &quot;String&quot;, 
+     * &quotjava.lang.String, java.io.File&quot becomes &quotString, File&quot;
+     * and so on. If fqName is null, return null. If fqName is &quot;&quot;, 
+     * return &quot;&quot;. 
+     */
+    public static String simpleName(String fqNames) {
+        if (fqNames == null)
+            return null;
+        String res = "";
+        boolean hasContent = false;
+        // We parse the string step by step to ensure we take
+        // fqNames that contains generics parameter in a whole.
+        ArrayList<String> fqNamesList = new ArrayList<String>();
+        int genericParametersDepth = 0;
+        StringBuffer buffer = new StringBuffer();
+        for (int i=0; i<fqNames.length(); i++) {
+          char c = fqNames.charAt(i);
+          if ('<' == c) {
+            genericParametersDepth++;
+          }
+          if ('>' == c) {
+            genericParametersDepth--;
+          }
+          if (',' != c || genericParametersDepth > 0) {
+            buffer.append(c);
+          } else if (',' == c) {
+            fqNamesList.add(buffer.toString().trim());
+            buffer = new StringBuffer(buffer.length());
+          }
+        }
+        fqNamesList.add(buffer.toString().trim());
+        for (String fqName : fqNamesList) {
+            // Assume this will be used inside a <nobr> </nobr> set of tags.
+            if (hasContent)
+                res += ", "; 
+            hasContent = true;
+            // Look for text within '<' and '>' in case this is a invocation of a generic
+            
+            int firstBracket = fqName.indexOf('<');
+            int lastBracket = fqName.lastIndexOf('>');
+            String genericParameter = null;
+            if (firstBracket != -1 && lastBracket != -1) {
+              genericParameter = simpleName(fqName.substring(firstBracket + 1, lastBracket));
+              fqName = fqName.substring(0, firstBracket);              
+            }
+            
+            int lastDot = fqName.lastIndexOf('.');
+            if (lastDot < 0) {
+                res += fqName; // Already as simple as possible
+            } else {
+                res += fqName.substring(lastDot+1);
+            }
+            if (genericParameter != null)
+              res += "&lt;" + genericParameter + "&gt;";            
+        }
+        return res;
+    }
+
+    /** 
+     * Find any existing comment and emit it. Add the new comment to the
+     * list of new comments. The first instance of the string "@first" in 
+     * a hand-written comment will be replaced by the first sentence from 
+     * the associated doc block, if such exists. Also replace @link by
+     * an HTML link.
+     *
+     * @param commentID The identifier for this comment.
+     * @param possibleComment A possible comment from another source.
+     * @param linkType 0 = remove, 1 = add, 2 = change
+     */
+    public void emitComment(String commentID, String possibleComment, 
+                            int linkType) {
+        if (noCommentsOnRemovals && linkType == 0) {
+            reportFile.println("  <TD>&nbsp;</TD>");
+            return;
+        }
+        if (noCommentsOnAdditions && linkType == 1) {
+            reportFile.println("  <TD>&nbsp;</TD>");
+            return;
+        }
+        if (noCommentsOnChanges && linkType == 2) {
+            reportFile.println("  <TD>&nbsp;</TD>");
+            return;
+        }
+
+        // We have to use this global hash table because the *Diff classes
+        // do not store the possible comment from the new *API object.
+        if (!noCommentsOnChanges && possibleComment == null) {
+            possibleComment = (String)Comments.allPossibleComments.get(commentID);
+        }
+        // Just use the first sentence of the possible comment.
+        if (possibleComment != null) {
+            int fsidx = RootDocToXML.endOfFirstSentence(possibleComment, false);
+            if (fsidx != -1 && fsidx != 0)
+                possibleComment = possibleComment.substring(0, fsidx+1);
+        }
+
+        String comment = Comments.getComment(existingComments_, commentID);
+        if (comment.compareTo(Comments.placeHolderText) == 0) {
+            if (possibleComment != null && 
+                possibleComment.indexOf("InsertOtherCommentsHere") == -1)
+                reportFile.println("  <TD VALIGN=\"TOP\">" + possibleComment + "</TD>");
+            else
+                reportFile.println("  <TD>&nbsp;</TD>");
+        } else {
+            int idx = comment.indexOf("@first");
+            if (idx == -1) {
+                reportFile.println("  <TD VALIGN=\"TOP\">" + Comments.convertAtLinks(comment, "", null, null) + "</TD>");
+            } else {
+                reportFile.print("  <TD VALIGN=\"TOP\">" + comment.substring(0, idx));
+                if (possibleComment != null && 
+                    possibleComment.indexOf("InsertOtherCommentsHere") == -1)
+                    reportFile.print(possibleComment);
+                reportFile.println(comment.substring(idx + 6) + "</TD>");
+            }
+        }
+        SingleComment newComment = new SingleComment(commentID, comment);
+        newComments_.addComment(newComment);
+    }
+    
+    /** Write the end of a table. */
+    public void writeTableEnd() {
+        reportFile.println("</TABLE>");
+        reportFile.println("&nbsp;");
+    } 
+
+    /** Write a newline out. */
+    public void writeText() {
+        reportFile.println();
+    } 
+
+    /** Write some text out. */
+    public void writeText(String text) {
+        reportFile.println(text);
+    } 
+
+    /** Emit some non-breaking space for indentation. */
+    public void indent(int indent) {
+        for (int i = 0; i < indent; i++)
+            reportFile.print("&nbsp;");
+    } 
+
+    /** 
+     * The name of the file to which the top-level HTML file is written, 
+     * and also the name of the subdirectory where most of the HTML appears,
+     * and also a prefix for the names of some of the files in that 
+     * subdirectory.
+     */
+    static String reportFileName = "changes";
+    
+    /** 
+     * The suffix of the file to which the HTML output is currently being 
+     * written. 
+     */
+    static String reportFileExt = ".html";
+    
+    /** 
+     * The file to which the HTML output is currently being written. 
+     */
+    static PrintWriter reportFile = null;
+
+    /** 
+     * The object which represents the top of the tree of differences
+     * between two APIs. It is only used indirectly when emitting a
+     * navigation bar.
+     */
+    static APIDiff apiDiff = null;
+
+    /** 
+     * If set, then do not suggest comments for removals from the first 
+     * sentence of the doc block of the old API. 
+     */
+    public static boolean noCommentsOnRemovals = false;
+
+    /** 
+     * If set, then do not suggest comments for additions from the first 
+     * sentence of the doc block of the new API. 
+     */
+    public static boolean noCommentsOnAdditions = false;
+
+    /** 
+     * If set, then do not suggest comments for changes from the first 
+     * sentence of the doc block of the new API. 
+     */
+    public static boolean noCommentsOnChanges = false;
+
+    /** 
+     * If set, then report changes in documentation (Javadoc comments) 
+     * between the old and the new API. The default is that this is not set.
+     */
+    public static boolean reportDocChanges = false;
+
+    /** 
+     * Define the prefix for HTML links to the existing set of Javadoc-
+     * generated documentation for the new API. E.g. For J2SE1.3.x, use
+     * "http://java.sun.com/j2se/1.3/docs/api/"
+     */
+    public static String newDocPrefix = "../";
+
+    /** 
+     * Define the prefix for HTML links to the existing set of Javadoc-
+     * generated documentation for the old API.
+     */
+    public static String oldDocPrefix = null;
+
+    /** To generate statistical output, set this to true. */
+    public static boolean doStats = false;
+
+    /** 
+     * The destination directory for output files.
+     */
+    public static String outputDir = null;
+    
+    /** 
+     * The destination directory for comments files (if not specified, uses outputDir)
+     */
+    public static String commentsDir = null;
+
+    /** 
+     * The title used on the first page of the report. By default, this is 
+     * &quot;API Differences Between &lt;name of old API&gt; and 
+     * &lt;name of new API&gt;&quot;. It can be
+     * set by using the -doctitle option.
+     */
+    public static String docTitle = null;
+
+    /** 
+     * The browser window title for the report. By default, this is 
+     * &quot;API Differences Between &lt;name of old API&gt; and 
+     * &lt;name of new API&gt;&quot;. It can be
+     * set by using the -windowtitle option.
+     */
+    public static String windowTitle = null;
+
+    /** The desired background color for JDiff tables. */
+    static final String bgcolor = "#FFFFFF";
+
+    /** Set to enable debugging output. */
+    private static final boolean trace = false;
+
+}
diff --git a/src/jdiff/HTMLStatistics.java b/src/jdiff/HTMLStatistics.java
new file mode 100755
index 0000000..6dada5c
--- /dev/null
+++ b/src/jdiff/HTMLStatistics.java
@@ -0,0 +1,491 @@
+package jdiff;
+
+import java.util.*;
+import java.io.*;
+import java.text.*;
+
+/**
+ * Emit an HTML file containing statistics about the differences.
+ * Statistical information only appears if the -stats argument is used.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+
+public class HTMLStatistics {
+
+    /** Constructor. */
+    public HTMLStatistics(HTMLReportGenerator h) {
+        h_ = h;
+    }   
+
+    /** The HTMLReportGenerator instance used to write HTML. */
+    private HTMLReportGenerator h_ = null;
+
+    /** 
+     * Emit the statistics HTML file.
+     */
+
+    public void emitStatistics(String filename, APIDiff apiDiff) {
+        try {
+            FileOutputStream fos = new FileOutputStream(filename);
+            h_.reportFile = new PrintWriter(fos);
+            // Write out the HTML header
+            h_.writeStartHTMLHeader();
+            String oldAPIName = "Old API";
+            if (apiDiff.oldAPIName_ != null)
+                oldAPIName = apiDiff.oldAPIName_;
+            String newAPIName = "New API";
+            if (apiDiff.newAPIName_ != null)
+                newAPIName = apiDiff.newAPIName_;
+            // Write out the title
+            h_.writeHTMLTitle("API Change Statistics");
+            h_.writeStyleSheetRef();
+            h_.writeText("</HEAD>");
+            h_.writeText("<body class=\"gc-documentation\">");
+
+           // writeText("<div class=\"g-section g-tpl-180\">");
+           // Add the nav bar for the summary page
+            
+            
+            // Write a customized navigation bar for the statistics page
+            h_.writeText("<!-- Start of nav bar -->");
+
+            SimpleDateFormat formatter
+              = new SimpleDateFormat ("yyyy.MM.dd HH:mm");
+            Date day = new Date();
+
+	    h_.writeText("<div id=\"gc-container\" style=\"padding-left:1em;padding-right:1em;\">");
+	    h_.writeText("<a name=\"top\"></a>");
+	    h_.writeText("<div id=\"gc-header\">");
+	    h_.writeText("  <div id=\"logo\" style=\"padding-left:1em;\">");
+	    h_.writeText("    <a href=\"../../../documentation.html\" target=\"_top\"><img style=\"border: 0;\" src=\"../../../assets-google/android-logo-sm.gif\" \"/></a>");
+	    h_.writeText("  </div> <!-- End logo -->");
+
+            h_.writeText("<div class=\"and-diff-id\">");
+            h_.writeText("<table class=\"diffspectable\">");
+            h_.writeText("<tr>");
+            h_.writeText("  <td colspan=\"2\" class=\"diffspechead\">API Diff Specification</td>");
+            h_.writeText("</tr>");
+	    h_.writeText("      <tr>");
+	    h_.writeText("        <td class=\"diffspec\">To Version:</td>");
+	    h_.writeText("        <td class=\"diffvaluenew\">" + newAPIName + "</td>");
+	    h_.writeText("      </tr>");
+	    h_.writeText("      <tr>");
+	    h_.writeText("        <td class=\"diffspec\">From Version:</td>");
+	    h_.writeText("        <td class=\"diffvalueold\">" + oldAPIName + "</td>");
+	    h_.writeText("      </tr>");
+            h_.writeText("<tr>");
+            h_.writeText("  <td class=\"diffspec\">Generated</td>");
+            h_.writeText("  <td class=\"diffvalue\">" + formatter.format( day ) + "</td>");
+            h_.writeText("</tr>");
+            h_.writeText("</table>");
+	    h_.writeText("  </div> <!-- End and-diff-id -->");
+
+	    h_.writeText("  <div class=\"and-diff-id\">");
+	    h_.writeText("    <table class=\"diffspectable\">");
+	    h_.writeText("      <tr>");
+	    h_.writeText("        <td class=\"diffspec\" colspan=\"2\"><a href=\"../changes.html\" target=\"_top\">Top of Report</a></div>");
+	    h_.writeText("      </tr>");
+ 	    h_.writeText("    </table>");
+	    h_.writeText("  </div> <!-- End and-diff-id -->");
+
+	    h_.writeText("</div> <!-- End gc-header -->");
+	    h_.writeText("<div id=\"codesiteContent\" style=\"margin-top: 70px;margin-bottom:80px;\">");
+
+            // Write the title in the body with some formatting
+            h_.writeText("<div style=\"xborder:1px solid yellow;vertical-align:top;padding:1em;margin-left:0;text-align:left;\">");
+            h_.writeText(" <H1 class=\"pagecontenth1\">API&nbsp;Change&nbsp;Statistics</H1>");
+            h_.writeText("</div>");
+
+
+            h_.writeText("<p>");
+            h_.writeText("The percent change statistic reported for all elements in each API is defined recursively as follows:</p>");
+            h_.writeText("<pre>"); 
+            h_.writeText("Percentage difference = 100 * (added + removed + 2*changed)");
+            h_.writeText("                        -----------------------------------");
+            h_.writeText("                        sum of public elements in BOTH APIs");
+            h_.writeText("</pre>"); 
+            h_.writeText("<p>where <code>added</code> is the number of packages added, <code>removed</code> is the number of packages removed, and <code>changed</code> is the number of packages changed.");
+            h_.writeText("This definition is applied recursively for the classes and their program elements, so the value for a changed package will be less than 1, unless every class in that package has changed.");
+            h_.writeText("The definition ensures that if all packages are removed and all new packages are");
+            h_.writeText("added, the change will be 100%. Values are rounded here, so a value of 0% indicates a percentage difference of less than 0.5%.</p>");
+
+            h_.writeText("<p>The overall difference between the two APIs is approximately <span style=\"color:222;font-weight:bold;\">" + (int)(apiDiff.pdiff) + "%</span>.");
+            h_.writeText("</p>");
+
+            h_.writeText("<br><h2 class=\"pagecontenth2\">Contents</h2>");
+            h_.writeText("<dl><dt><a href=\"#packages\">Changed Packages</a></dt> <dd>Sorted by percentage difference</dd>");
+            h_.writeText("<dt><a href=\"#classes\">Changed Classes and <i>Interfaces</i></a></dt><dd>Sorted by percentage difference</dd>");
+            h_.writeText("<dt><a href=\"#numbers\">Total of Differences</a></dt><dd>Listed by number and type</dd></dl>");
+
+            h_.writeText("<br>");
+            h_.writeText("<a name=\"packages\"></a>");
+            h_.writeText("<h2 class=\"pagecontenth2\">Changed Packages, Sorted by Percentage Difference</h2>");
+            emitPackagesByDiff(apiDiff);
+
+            h_.writeText("<br>");
+            h_.writeText("<a name=\"classes\"></a>");
+            h_.writeText("<h2 class=\"pagecontenth2\">Changed Classes and <i>Interfaces</i>, Sorted by Percentage Difference</h2>");
+            emitClassesByDiff(apiDiff);
+
+            h_.writeText("<br>");
+            h_.writeText("<a name=\"numbers\"></a>");
+            h_.writeText("<h2 class=\"pagecontenth2\">Total of Differences, by Number and Type</h2>");
+            h_.writeText("<p>");
+            h_.writeText("The table below lists the numbers of program elements (packages, classes, constructors, methods, and fields) that were removed, added or changed. The table includes only the highest-level program elements &mdash; that is, if a class with two methods was added, the number of methods added does not include those two methods, but the number of classes added does include that class.");
+            h_.writeText("</p>");
+
+            emitNumbersByElement(apiDiff);
+            
+	    h_.writeText("</div><!-- end codesitecontent -->");
+            h_.writeText("<div style=\"padding-left: 10px; padding-right: 10px; margin-top: 0; padding-bottom: 15px;\">");
+            h_.writeText("  <table style=\"width: 100%; border: none;\"><tr>");
+            h_.writeText("    <td style=\"text-align:center;font-size: 10pt; border: none; color: ccc;\"> ");
+            h_.writeText("      <span>&copy;2008 Google - ");
+            h_.writeText("            <a href=\"http://code.google.com\">Code Home</a> - ");
+            h_.writeText("            <a href=\"http://www.google.com/accounts/TOS\">Site Terms of Sservice</a> - "); 
+            h_.writeText("            <a href=\"http://www.google.com/privacy.html\">Privacy Policy</a> ");
+            h_.writeText("      </span>");
+            h_.writeText("      <div style=\"xborder 1px solid red;position:relative;margin-top:-2em;" );
+            h_.writeText("        font-size:8pt;color:aaa;text-align:right;\">");
+            h_.writeText("        <em>Generated by <a href=\"http://www.jdiff.org/\">JDiff</a></em><br><img ");
+            h_.writeText("        align=\"right\" src=\"../../../assets/jdiff_logo.gif\">");
+            h_.writeText("      </span>");
+            h_.writeText("    </td>");
+            h_.writeText(" </tr></table>");
+            h_.writeText("</div>");
+            h_.writeText("</div><!-- end gc-containter -->");
+
+            h_.writeText("<script src=\"http://www.google-analytics.com/ga.js\" type=\"text/javascript\">");
+            h_.writeText("</script>");
+            h_.writeText("<script type=\"text/javascript\">");
+            h_.writeText("  try {");
+            h_.writeText("    var pageTracker = _gat._getTracker(\"UA-18071-1\");");
+            h_.writeText("    pageTracker._setAllowAnchor(true);");
+            h_.writeText("    pageTracker._initData();");
+            h_.writeText("    pageTracker._trackPageview();");
+            h_.writeText("  } catch(e) {}");
+            h_.writeText("</script>");
+
+            h_.writeText("</BODY></HTML>");
+            h_.reportFile.close();
+        } catch(IOException e) {
+            System.out.println("IO Error while attempting to create " + filename);
+            System.out.println("Error: " + e.getMessage());
+            System.exit(1);
+        }
+    }
+
+    /**
+     * Emit all packages sorted by percentage difference, and a histogram
+     * of the values.
+     */
+    public void emitPackagesByDiff(APIDiff apiDiff) {
+        
+        Collections.sort(apiDiff.packagesChanged, new ComparePkgPdiffs());
+
+        // Write out the table start
+        h_.writeText("<TABLE summary=\"Packages sorted by percentage difference\" BORDER=\"1\" WIDTH=\"100%\" cellspacing=\"0\" cellpadding=\"0\">");
+        h_.writeText("<TR WIDTH=\"20%\">");
+        h_.writeText("  <TH>Percentage<br>Difference</TH>");
+        h_.writeText("  <TH>Package</TH>");
+        h_.writeText("</TR>");
+
+        int[] hist = new int[101];
+        for (int i = 0; i < 101; i++) {
+            hist[i] = 0;
+        }
+
+        Iterator iter = apiDiff.packagesChanged.iterator();
+        while (iter.hasNext()) {
+            PackageDiff pkg = (PackageDiff)(iter.next());
+            int bucket = (int)(pkg.pdiff);
+            hist[bucket]++;
+            h_.writeText("<TR>");
+            if (bucket != 0)
+                h_.writeText("  <TD ALIGN=\"center\">" + bucket + "</TD>");
+            else
+                h_.writeText("  <TD ALIGN=\"center\">&lt;1</TD>");
+            h_.writeText("  <TD><A HREF=\"pkg_" + pkg.name_ + h_.reportFileExt + "\">" + pkg.name_ + "</A></TD>");
+            h_.writeText("</TR>");
+        }
+
+        h_.writeText("</TABLE>");
+        
+        /* Emit the histogram of the results
+        h_.writeText("<hr>");
+        h_.writeText("<p><a name=\"packages_hist\"></a>");
+        h_.writeText("<TABLE summary=\"Histogram of the package percentage differences\" BORDER=\"1\" cellspacing=\"0\" cellpadding=\"0\">");
+        h_.writeText("<TR>");
+        h_.writeText("  <TD ALIGN=\"center\" bgcolor=\"#EEEEFF\"><FONT size=\"+1\"><b>Percentage<br>Difference</b></FONT></TD>");
+        h_.writeText("  <TD ALIGN=\"center\" bgcolor=\"#EEEEFF\"><FONT size=\"+1\"><b>Frequency</b></FONT></TD>");
+        h_.writeText("  <TD width=\"300\" ALIGN=\"center\" bgcolor=\"#EEEEFF\"><FONT size=\"+1\"><b>Percentage Frequency</b></FONT></TD>");
+        h_.writeText("</TR>");
+
+        double total = 0;
+        for (int i = 0; i < 101; i++) {
+            total += hist[i];
+        }
+        for (int i = 0; i < 101; i++) {
+            if (hist[i] != 0) {
+                h_.writeText("<TR>");
+                h_.writeText("  <TD ALIGN=\"center\">" + i + "</TD>");
+                h_.writeText("  <TD>" + (hist[i]/total) + "</TD>");
+                h_.writeText("  <TD><img alt=\"|\" src=\"../black.gif\" height=20 width=" + (hist[i]*300/total) + "></TD>");
+                h_.writeText("</TR>");
+            }
+        }
+        // Repeat the data in a format which is easier for spreadsheets
+        h_.writeText("<!-- START_PACKAGE_HISTOGRAM");
+        for (int i = 0; i < 101; i++) {
+            if (hist[i] != 0) {
+                h_.writeText(i + "," + (hist[i]/total));
+            }
+        }
+        h_.writeText("END_PACKAGE_HISTOGRAM -->");
+        
+        h_.writeText("</TABLE>");
+	*/
+    }
+
+    /**
+     * Emit all classes sorted by percentage difference, and a histogram
+     * of the values..
+     */
+    public void emitClassesByDiff(APIDiff apiDiff) {
+        // Add all the changed classes to a list
+        List allChangedClasses = new ArrayList();
+        Iterator iter = apiDiff.packagesChanged.iterator();
+        while (iter.hasNext()) {
+            PackageDiff pkg = (PackageDiff)(iter.next());
+            if (pkg.classesChanged != null) {
+                // Add the package name to the class name
+                List cc = new ArrayList(pkg.classesChanged);
+                Iterator iter2 = cc.iterator();
+                while (iter2.hasNext()) {
+                    ClassDiff classDiff = (ClassDiff)(iter2.next());
+                    classDiff.name_ = pkg.name_ + "." + classDiff.name_;
+                }
+                allChangedClasses.addAll(cc);
+            }
+        }
+        Collections.sort(allChangedClasses, new CompareClassPdiffs());
+
+        // Write out the table start
+        h_.writeText("<TABLE summary=\"Classes sorted by percentage difference\" BORDER=\"1\" WIDTH=\"100%\" cellspacing=\"0\" cellpadding=\"0\">");
+        h_.writeText("<TR WIDTH=\"20%\">");
+        h_.writeText("  <TH><b>Percentage<br>Difference</b></TH>");
+        h_.writeText("  <TH><b>Class or <i>Interface</i></b></TH>");
+        h_.writeText("</TR>");
+
+        int[] hist = new int[101];
+        for (int i = 0; i < 101; i++) {
+            hist[i] = 0;
+        }
+
+        iter = allChangedClasses.iterator();
+        while (iter.hasNext()) {
+            ClassDiff classDiff = (ClassDiff)(iter.next());
+            int bucket = (int)(classDiff.pdiff);
+            hist[bucket]++;
+            h_.writeText("<TR>");
+            if (bucket != 0)
+                h_.writeText("  <TD ALIGN=\"center\">" + bucket + "</TD>");
+            else
+                h_.writeText("  <TD ALIGN=\"center\">&lt;1</TD>");
+            h_.writeText("  <TD><A HREF=\"" + classDiff.name_ + h_.reportFileExt + "\">");
+            if (classDiff.isInterface_)
+                h_.writeText("<i>" + classDiff.name_ + "</i></A></TD>");
+            else
+                h_.writeText(classDiff.name_ + "</A></TD>");
+            h_.writeText("</TR>");
+        }
+
+        h_.writeText("</TABLE>");
+
+        /* Emit the histogram of the results
+        h_.writeText("<hr>");
+        h_.writeText("<p><a name=\"classes_hist\"></a>");
+        h_.writeText("<TABLE summary=\"Histogram of the class percentage differences\" BORDER=\"1\" cellspacing=\"0\" cellpadding=\"0\">");
+        h_.writeText("<TR>");
+        h_.writeText("  <TD ALIGN=\"center\" bgcolor=\"#EEEEFF\"><FONT size=\"+1\"><b>Percentage<br>Difference</b></FONT></TD>");
+        h_.writeText("  <TD ALIGN=\"center\" bgcolor=\"#EEEEFF\"><FONT size=\"+1\"><b>Frequency</b></FONT></TD>");
+        h_.writeText("  <TD width=\"300\" ALIGN=\"center\" bgcolor=\"#EEEEFF\"><FONT size=\"+1\"><b>Percentage Frequency</b></FONT></TD>");
+        h_.writeText("</TR>");
+
+        double total = 0;
+        for (int i = 0; i < 101; i++) {
+            total += hist[i];
+        }
+        for (int i = 0; i < 101; i++) {
+            if (hist[i] != 0) {
+                h_.writeText("<TR>");
+                h_.writeText("  <TD ALIGN=\"center\">" + i + "</TD>");
+                h_.writeText("  <TD>" + (hist[i]/total) + "</TD>");
+                h_.writeText("  <TD><img alt=\"|\" src=\"../black.gif\" height=20 width=" + (hist[i]*300/total) + "></TD>");
+                h_.writeText("</TR>");
+            }
+        }
+        // Repeat the data in a format which is easier for spreadsheets
+        h_.writeText("<!-- START_CLASS_HISTOGRAM");
+        for (int i = 0; i < 101; i++) {
+            if (hist[i] != 0) {
+                h_.writeText(i + "," + (hist[i]/total));
+            }
+        }
+        h_.writeText("END_CLASS_HISTOGRAM -->");
+        
+        h_.writeText("</TABLE>");
+	*/
+    }
+
+    /**
+     * Emit a table of numbers of removals, additions and changes by
+     * package, class, constructor, method and field.
+     */
+    public void emitNumbersByElement(APIDiff apiDiff) {
+
+        // Local variables to hold the values
+        int numPackagesRemoved = apiDiff.packagesRemoved.size();
+        int numPackagesAdded = apiDiff.packagesAdded.size();
+        int numPackagesChanged = apiDiff.packagesChanged.size();
+
+        int numClassesRemoved = 0;
+        int numClassesAdded = 0;
+        int numClassesChanged = 0;
+
+        int numCtorsRemoved = 0;
+        int numCtorsAdded = 0;
+        int numCtorsChanged = 0;
+
+        int numMethodsRemoved = 0;
+        int numMethodsAdded = 0;
+        int numMethodsChanged = 0;
+
+        int numFieldsRemoved = 0;
+        int numFieldsAdded = 0;
+        int numFieldsChanged = 0;
+
+        int numRemoved = 0;
+        int numAdded = 0;
+        int numChanged = 0;
+
+        // Calculate the values
+        Iterator iter = apiDiff.packagesChanged.iterator();
+        while (iter.hasNext()) {
+            PackageDiff pkg = (PackageDiff)(iter.next());
+            numClassesRemoved += pkg.classesRemoved.size();
+            numClassesAdded += pkg.classesAdded.size();
+            numClassesChanged += pkg.classesChanged.size();
+
+            Iterator iter2 = pkg.classesChanged.iterator();
+            while (iter2.hasNext()) {
+                 ClassDiff classDiff = (ClassDiff)(iter2.next());
+                 numCtorsRemoved += classDiff.ctorsRemoved.size();
+                 numCtorsAdded += classDiff.ctorsAdded.size();
+                 numCtorsChanged += classDiff.ctorsChanged.size();
+                 
+                 numMethodsRemoved += classDiff.methodsRemoved.size();
+                 numMethodsAdded += classDiff.methodsAdded.size();
+                 numMethodsChanged += classDiff.methodsChanged.size();
+                 
+                 numFieldsRemoved += classDiff.fieldsRemoved.size();
+                 numFieldsAdded += classDiff.fieldsAdded.size();
+                 numFieldsChanged += classDiff.fieldsChanged.size();
+            }
+        }
+        
+        // Write out the table
+        h_.writeText("<TABLE summary=\"Number of differences\" BORDER=\"1\" WIDTH=\"100%\" cellspacing=\"0\" cellpadding=\"0\">");
+        h_.writeText("<TR>");
+        h_.writeText("  <TH COLSPAN=5 NOWRAP>");
+        h_.writeText("  Number of Differences</TH>");
+        h_.writeText("</TR>");
+        h_.writeText("<TR>");
+        h_.writeText("  <TH>&nbsp;</TD>");
+        h_.writeText("  <TH ALIGN=\"center\"><b>Removals</b></TH>");
+        h_.writeText("  <TH ALIGN=\"center\"><b>Additions</b></TH>");
+        h_.writeText("  <TH ALIGN=\"center\"><b>Changes</b></TH>");
+        h_.writeText("  <TH ALIGN=\"center\"><b>Total</b></TH>");
+        h_.writeText("</TR>");
+
+        h_.writeText("<TR>");
+        h_.writeText("  <TD>Packages</TD>");
+        h_.writeText("  <TD ALIGN=\"right\">" + numPackagesRemoved + "</TD>");
+        h_.writeText("  <TD ALIGN=\"right\">" + numPackagesAdded + "</TD>");
+        h_.writeText("  <TD ALIGN=\"right\">" + numPackagesChanged + "</TD>");
+        int numPackages = numPackagesRemoved + numPackagesAdded + numPackagesChanged;
+        h_.writeText("  <TD ALIGN=\"right\">" + numPackages + "</TD>");
+        h_.writeText("</TR>");
+
+        numRemoved += numPackagesRemoved;
+        numAdded += numPackagesAdded;
+        numChanged += numPackagesChanged;
+
+        h_.writeText("<TR>");
+        h_.writeText("  <TD>Classes and <i>Interfaces</i></TD>");
+        h_.writeText("  <TD ALIGN=\"right\">" + numClassesRemoved + "</TD>");
+        h_.writeText("  <TD ALIGN=\"right\">" + numClassesAdded + "</TD>");
+        h_.writeText("  <TD ALIGN=\"right\">" + numClassesChanged + "</TD>");
+        int numClasses = numClassesRemoved + numClassesAdded + numClassesChanged;
+        h_.writeText("  <TD ALIGN=\"right\">" + numClasses + "</TD>");
+        h_.writeText("</TR>");
+
+        numRemoved += numClassesRemoved;
+        numAdded += numClassesAdded;
+        numChanged += numClassesChanged;
+
+        h_.writeText("<TR>");
+        h_.writeText("  <TD>Constructors</TD>");
+        h_.writeText("  <TD ALIGN=\"right\">" + numCtorsRemoved + "</TD>");
+        h_.writeText("  <TD ALIGN=\"right\">" + numCtorsAdded + "</TD>");
+        h_.writeText("  <TD ALIGN=\"right\">" + numCtorsChanged + "</TD>");
+        int numCtors = numCtorsRemoved + numCtorsAdded + numCtorsChanged;
+        h_.writeText("  <TD ALIGN=\"right\">" + numCtors + "</TD>");
+        h_.writeText("</TR>");
+
+        numRemoved += numCtorsRemoved;
+        numAdded += numCtorsAdded;
+        numChanged += numCtorsChanged;
+
+        h_.writeText("<TR>");
+        h_.writeText("  <TD>Methods</TD>");
+        h_.writeText("  <TD ALIGN=\"right\">" + numMethodsRemoved + "</TD>");
+        h_.writeText("  <TD ALIGN=\"right\">" + numMethodsAdded + "</TD>");
+        h_.writeText("  <TD ALIGN=\"right\">" + numMethodsChanged + "</TD>");
+        int numMethods = numMethodsRemoved + numMethodsAdded + numMethodsChanged;
+        h_.writeText("  <TD ALIGN=\"right\">" + numMethods + "</TD>");
+        h_.writeText("</TR>");
+
+        numRemoved += numMethodsRemoved;
+        numAdded += numMethodsAdded;
+        numChanged += numMethodsChanged;
+
+        h_.writeText("<TR>");
+        h_.writeText("  <TD>Fields</TD>");
+        h_.writeText("  <TD ALIGN=\"right\">" + numFieldsRemoved + "</TD>");
+        h_.writeText("  <TD ALIGN=\"right\">" + numFieldsAdded + "</TD>");
+        h_.writeText("  <TD ALIGN=\"right\">" + numFieldsChanged + "</TD>");
+        int numFields = numFieldsRemoved + numFieldsAdded + numFieldsChanged;
+        h_.writeText("  <TD ALIGN=\"right\">" + numFields + "</TD>");
+        h_.writeText("</TR>");
+
+        numRemoved += numFieldsRemoved;
+        numAdded += numFieldsAdded;
+        numChanged += numFieldsChanged;
+
+        h_.writeText("<TR>");
+        h_.writeText("  <TD><b>Total</b></TD>");
+        h_.writeText("  <TD ALIGN=\"right\">" + numRemoved + "</TD>");
+        h_.writeText("  <TD ALIGN=\"right\">" + numAdded + "</TD>");
+        h_.writeText("  <TD ALIGN=\"right\">" + numChanged + "</TD>");
+        int total = numRemoved + numAdded + numChanged;
+        h_.writeText("  <TD ALIGN=\"right\">" + total + "</TD>");
+        h_.writeText("</TR>");
+
+        h_.writeText("</TABLE>");
+    }
+
+}
+
diff --git a/src/jdiff/JDiff.java b/src/jdiff/JDiff.java
new file mode 100755
index 0000000..14a7a97
--- /dev/null
+++ b/src/jdiff/JDiff.java
@@ -0,0 +1,297 @@
+package jdiff;
+
+import com.sun.javadoc.*;
+
+import java.util.*;
+import java.io.*;
+import java.lang.reflect.*; // Used for invoking Javadoc indirectly
+import java.lang.Runtime;
+import java.lang.Process;
+
+/**
+ * Generates HTML describing the changes between two sets of Java source code.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com.
+ */
+public class JDiff extends Doclet {
+
+    public static LanguageVersion languageVersion(){
+      return LanguageVersion.JAVA_1_5;
+    } 
+    /**
+     * Doclet-mandated start method. Everything begins here.
+     *
+     * @param root  a RootDoc object passed by Javadoc
+     * @return true if document generation succeeds
+     */
+    public static boolean start(RootDoc root) {
+        if (root != null)
+            System.out.println("JDiff: doclet started ...");
+        JDiff jd = new JDiff();
+        return jd.startGeneration(root);
+    }
+
+    /**
+     * Generate the summary of the APIs.
+     *
+     * @param root  the RootDoc object passed by Javadoc
+     * @return true if no problems encountered within JDiff
+     */
+    protected boolean startGeneration(RootDoc newRoot) {
+        long startTime = System.currentTimeMillis();
+
+        // Open the file where the XML representing the API will be stored.
+        // and generate the XML for the API into it.
+        if (writeXML) {
+            RootDocToXML.writeXML(newRoot);           
+        }
+
+        if (compareAPIs) {
+	    String tempOldFileName = oldFileName;
+	    if (oldDirectory != null) {
+		tempOldFileName = oldDirectory;
+		if (!tempOldFileName.endsWith(JDiff.DIR_SEP)) {
+		    tempOldFileName += JDiff.DIR_SEP;
+		}
+		tempOldFileName += oldFileName;
+	    }
+
+            // Check the file for the old API exists
+            File f = new File(tempOldFileName);
+            if (!f.exists()) {
+                System.out.println("Error: file '" + tempOldFileName + "' does not exist for the old API");
+                return false;
+            }
+            // Check the file for the new API exists
+
+	    String tempNewFileName = newFileName;
+            if (newDirectory != null) {
+		tempNewFileName = newDirectory;
+		if (!tempNewFileName.endsWith(JDiff.DIR_SEP)) {
+		    tempNewFileName += JDiff.DIR_SEP;
+		}
+		tempNewFileName += newFileName;
+            }
+            f = new File(tempNewFileName);
+            if (!f.exists()) {
+                System.out.println("Error: file '" + tempNewFileName + "' does not exist for the new API");
+                return false;
+            }
+
+            // Read the file where the XML representing the old API is stored
+            // and create an API object for it.
+            System.out.print("JDiff: reading the old API in from file '" + tempOldFileName + "'...");
+            // Read the file in, but do not add any text to the global comments
+            API oldAPI = XMLToAPI.readFile(tempOldFileName, false, oldFileName);
+            
+            // Read the file where the XML representing the new API is stored
+            // and create an API object for it.
+            System.out.print("JDiff: reading the new API in from file '" + tempNewFileName + "'...");
+            // Read the file in, and do add any text to the global comments
+            API newAPI = XMLToAPI.readFile(tempNewFileName, true, newFileName);
+            
+            // Compare the old and new APIs.
+            APIComparator comp = new APIComparator();
+            
+            comp.compareAPIs(oldAPI, newAPI);
+            
+            // Read the file where the XML for comments about the changes between
+            // the old API and new API is stored and create a Comments object for 
+            // it. The Comments object may be null if no file exists.
+            int suffix = oldFileName.lastIndexOf('.');
+            String commentsFileName = "user_comments_for_" + oldFileName.substring(0, suffix);
+            suffix = newFileName.lastIndexOf('.');
+            commentsFileName += "_to_" + newFileName.substring(0, suffix) + ".xml";
+            commentsFileName = commentsFileName.replace(' ', '_');
+                if (HTMLReportGenerator.commentsDir !=null) {
+                  commentsFileName = HTMLReportGenerator.commentsDir + DIR_SEP + commentsFileName;
+                } else if (HTMLReportGenerator.outputDir != null) {
+                  commentsFileName = HTMLReportGenerator.outputDir + DIR_SEP + commentsFileName;
+                }
+            System.out.println("JDiff: reading the comments in from file '" + commentsFileName + "'...");
+            Comments existingComments = Comments.readFile(commentsFileName);
+            if (existingComments == null)
+                System.out.println(" (the comments file will be created)");
+            
+            // Generate an HTML report which summarises all the API differences.
+            HTMLReportGenerator reporter = new HTMLReportGenerator();
+            reporter.generate(comp, existingComments);
+            
+            // Emit messages about which comments are now unused and
+            // which are new.
+            Comments newComments = reporter.getNewComments();
+            Comments.noteDifferences(existingComments, newComments);
+            
+            // Write the new comments out to the same file, with unused comments
+            // now commented out.
+            System.out.println("JDiff: writing the comments out to file '" + commentsFileName + "'...");
+            Comments.writeFile(commentsFileName, newComments);
+        }
+
+        System.out.print("JDiff: finished (took " + (System.currentTimeMillis() - startTime)/1000 + "s");
+        if (writeXML)
+            System.out.println(", not including scanning the source files)."); 
+        else if (compareAPIs)
+            System.out.println(").");
+       return true;
+    }
+
+//
+// Option processing
+// 
+
+    /**
+     * This method is called by Javadoc to
+     * parse the options it does not recognize. It then calls
+     * {@link #validOptions} to validate them.
+     *
+     * @param option  a String containing an option
+     * @return an int telling how many components that option has
+     */
+    public static int optionLength(String option) {
+        return Options.optionLength(option);
+    }
+
+    /**
+     * After parsing the available options using {@link #optionLength},
+     * Javadoc invokes this method with an array of options-arrays.
+     *
+     * @param options   an array of String arrays, one per option
+     * @param reporter  a DocErrorReporter for generating error messages
+     * @return true if no errors were found, and all options are
+     *         valid
+     */
+    public static boolean validOptions(String[][] options, 
+                                       DocErrorReporter reporter) {
+        return Options.validOptions(options, reporter);
+    }
+    
+    /** 
+     * This method is only called when running JDiff as a standalone
+     * application, and uses ANT to execute the build configuration in the 
+     * XML configuration file passed in.
+     */
+    public static void main(String[] args) {
+        if (args.length == 0) {
+            //showUsage();
+            System.out.println("Looking for a local 'build.xml' configuration file");
+        } else if (args.length == 1) {
+            if (args[0].compareTo("-help") == 0 ||
+                args[0].compareTo("-h") == 0 ||
+                args[0].compareTo("?") == 0) {
+                showUsage();
+            } else if (args[0].compareTo("-version") == 0) {
+                System.out.println("JDiff version: " + JDiff.version);
+            }
+            return;
+        }
+        int rc = runAnt(args);
+        return;
+    }
+
+    /** 
+     * Display usage information for JDiff.
+     */
+    public static void showUsage() {
+        System.out.println("usage: java jdiff.JDiff [-version] [-buildfile <XML configuration file>]");
+        System.out.println("If no build file is specified, the local build.xml file is used.");
+    }
+
+    /** 
+     * Invoke ANT by reflection. 
+     *
+     * @return The integer return code from running ANT.
+     */
+    public static int runAnt(String[] args) {
+        String className = null;
+        Class c = null;
+        try {
+            className = "org.apache.tools.ant.Main";
+            c = Class.forName(className);
+        } catch (ClassNotFoundException e1) {
+            System.err.println("Error: ant.jar not found on the classpath");
+            return -1;
+        }
+        try {
+            Class[] methodArgTypes = new Class[1];
+            methodArgTypes[0] = args.getClass();
+            Method mainMethod = c.getMethod("main", methodArgTypes);
+            Object[] methodArgs = new Object[1];
+            methodArgs[0] = args;
+            // The object can be null because the method is static
+            Integer res = (Integer)mainMethod.invoke(null, methodArgs);
+            System.gc(); // Clean up after running ANT
+            return res.intValue();
+        } catch (NoSuchMethodException e2) {
+            System.err.println("Error: method \"main\" 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 \"main\" could not be invoked");
+            e5.printStackTrace();
+        } catch (Exception e6) {
+            System.err.println("Error: ");
+            e6.printStackTrace();
+        }
+        System.gc(); // Clean up after running ANT
+        return -1;
+    }
+
+    /** 
+     * The name of the file where the XML representing the old API is
+     * stored. 
+     */
+    static String oldFileName = "old_java.xml";
+
+    /** 
+     * The name of the directory where the XML representing the old API is
+     * stored. 
+     */
+    static String oldDirectory = null;
+
+    /** 
+     * The name of the file where the XML representing the new API is 
+     * stored. 
+     */
+    static String newFileName = "new_java.xml";
+
+    /** 
+     * The name of the directory where the XML representing the new API is 
+     * stored. 
+     */
+    static String newDirectory = null;
+
+    /** If set, then generate the XML for an API and exit. */
+    static boolean writeXML = false;
+
+    /** If set, then read in two XML files and compare their APIs. */
+    static boolean compareAPIs = false;
+
+    /** 
+     * The file separator for the local filesystem, forward or backward slash. 
+     */
+    static String DIR_SEP = System.getProperty("file.separator");
+
+    /** Details for where to find JDiff. */
+    static final String jDiffLocation = "http://www.jdiff.org";
+    /** Contact email address for the primary JDiff maintainer. */
+    static final String authorEmail = "mdoar@pobox.com";
+
+    /** A description for HTML META tags. */
+    static final String jDiffDescription = "JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.";
+    /** Keywords for HTML META tags. */
+    static final String jDiffKeywords = "diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet";
+
+    /** The current JDiff version. */
+    static final String version = "1.1.0";
+
+    /** The current virtual machine version. */
+    static String javaVersion = System.getProperty("java.version");
+
+    /** Set to enable increased logging verbosity for debugging. */
+    private static boolean trace = false;
+
+} //JDiff
diff --git a/src/jdiff/JDiffAntTask.java b/src/jdiff/JDiffAntTask.java
new file mode 100755
index 0000000..e5b14ac
--- /dev/null
+++ b/src/jdiff/JDiffAntTask.java
@@ -0,0 +1,536 @@
+package jdiff;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Javadoc;
+import org.apache.tools.ant.taskdefs.Javadoc.DocletInfo;
+import org.apache.tools.ant.taskdefs.Javadoc.DocletParam;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.DirSet;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * An Ant task to produce a simple JDiff report. More complex reports still
+ * need parameters that are controlled by the Ant Javadoc task.
+ */
+public class JDiffAntTask {
+
+    public void execute() throws BuildException {
+	jdiffHome = project.getProperty("JDIFF_HOME");
+	if (jdiffHome == null || jdiffHome.compareTo("") == 0 | 
+	    jdiffHome.compareTo("(not set)") == 0) {
+	    throw new BuildException("Error: invalid JDIFF_HOME property. Set it in the build file to the directory where jdiff is installed");
+	}
+        project.log(" JDiff home: " + jdiffHome, Project.MSG_INFO);
+
+	jdiffClassPath = jdiffHome + DIR_SEP + "jdiff.jar" +
+	    System.getProperty("path.separator") +
+	    jdiffHome + DIR_SEP + "xerces.jar";
+
+	// TODO detect and set verboseAnt
+
+	// Create, if necessary, the directory for the JDiff HTML report
+        if (!destdir.mkdir() && !destdir.exists()) {
+	    throw new BuildException(getDestdir() + " is not a valid directory");
+	} else {
+	    project.log(" Report location: " + getDestdir() + DIR_SEP 
+			+ "changes.html", Project.MSG_INFO);
+	}
+	// Could also output the other parameters used for JDiff here
+ 	
+	// Check that there are indeed two projects to compare. If there
+	// are no directories in the project, let Javadoc do the complaining
+	if (oldProject == null || newProject == null) {
+	    throw new BuildException("Error: two projects are needed, one <old> and one <new>");
+	}
+
+	/*
+	// Display the directories being compared, and some name information
+	if (getVerbose()) {
+	    project.log("Older version: " + oldProject.getName(), 
+			Project.MSG_INFO);
+	    project.log("Included directories for older version:", 
+			Project.MSG_INFO);
+	    DirectoryScanner ds = 
+		oldProject.getDirset().getDirectoryScanner(project);
+	    String[] files = ds.getIncludedDirectories();
+	    for (int i = 0; i < files.length; i++) {
+		project.log(" " + files[i], Project.MSG_INFO);
+	    }
+	    ds = null;
+	    
+	    project.log("Newer version: " + newProject.getName(), 
+			Project.MSG_INFO);
+	    project.log("Included directories for newer version:", 
+			Project.MSG_INFO);
+	    ds = newProject.getDirset().getDirectoryScanner(project);
+	    files = ds.getIncludedDirectories();
+	    for (int i = 0; i < files.length; i++) {
+		project.log(" " + files[i], Project.MSG_INFO);
+	    }
+	}
+	*/
+
+	// Call Javadoc twice to generate Javadoc for each project
+	generateJavadoc(oldProject);
+	generateJavadoc(newProject);
+
+	// Call Javadoc three times for JDiff.
+	generateXML(oldProject);
+	generateXML(newProject);
+	compareXML(oldProject.getName(), newProject.getName());
+
+	// Repeat some useful information
+	project.log(" Report location: " + getDestdir() + DIR_SEP 
+		    + "changes.html", Project.MSG_INFO);
+    }
+
+    /**
+     * Convenient method to create a Javadoc task, configure it and run it
+     * to generate the XML representation of a project's source files.
+     *
+     * @param proj The current Project
+     */
+    protected void generateXML(ProjectInfo proj) {
+	String apiname = proj.getName();
+	Javadoc jd = initJavadoc("Analyzing " + apiname);
+	jd.setDestdir(getDestdir());
+	addSourcePaths(jd, proj);
+
+	// Tell Javadoc which packages we want to scan. 
+	// JDiff works with packagenames, not sourcefiles.
+	jd.setPackagenames(getPackageList(proj));
+	
+	// Create the DocletInfo first so we have a way to use it to add params
+	DocletInfo dInfo = jd.createDoclet();
+	jd.setDoclet("jdiff.JDiff");
+	jd.setDocletPath(new Path(project, jdiffClassPath));
+	
+	// Now set up some parameters for the JDiff doclet.
+	DocletParam dp1 = dInfo.createParam();
+	dp1.setName("-apiname");
+	dp1.setValue(apiname);
+	DocletParam dp2 = dInfo.createParam();
+	dp2.setName("-baseURI");
+	dp2.setValue("http://www.w3.org");
+	// Put the generated file in the same directory as the report
+	DocletParam dp3 = dInfo.createParam();
+	dp3.setName("-apidir");
+	dp3.setValue(getDestdir().toString());
+	
+	// Execute the Javadoc command to generate the XML file.
+	jd.perform();
+    }
+
+    /**
+     * Convenient method to create a Javadoc task, configure it and run it
+     * to compare the XML representations of two instances of a project's 
+     * source files, and generate an HTML report summarizing the differences.
+     *
+     * @param oldapiname The name of the older version of the project
+     * @param newapiname The name of the newer version of the project
+     */
+    protected void compareXML(String oldapiname, String newapiname) {
+	Javadoc jd = initJavadoc("Comparing versions");
+	jd.setDestdir(getDestdir());
+	jd.setPrivate(true);
+
+	// Tell Javadoc which files we want to scan - a dummy file in this case
+	jd.setSourcefiles(jdiffHome + DIR_SEP + "Null.java");
+	
+	// Create the DocletInfo first so we have a way to use it to add params
+	DocletInfo dInfo = jd.createDoclet();
+	jd.setDoclet("jdiff.JDiff");
+	jd.setDocletPath(new Path(project, jdiffClassPath));
+	
+	// Now set up some parameters for the JDiff doclet.
+	DocletParam dp1 = dInfo.createParam();
+	dp1.setName("-oldapi");
+	dp1.setValue(oldapiname);
+	DocletParam dp2 = dInfo.createParam();
+	dp2.setName("-newapi");
+	dp2.setValue(newapiname);
+	// Get the generated XML files from the same directory as the report
+	DocletParam dp3 = dInfo.createParam();
+	dp3.setName("-oldapidir");
+	dp3.setValue(getDestdir().toString());
+	DocletParam dp4 = dInfo.createParam();
+	dp4.setName("-newapidir");
+	dp4.setValue(getDestdir().toString());
+
+	// Assume that Javadoc reports already exist in ../"apiname"
+	DocletParam dp5 = dInfo.createParam();
+	dp5.setName("-javadocold");
+	dp5.setValue(".." + DIR_SEP + oldapiname + DIR_SEP);
+	DocletParam dp6 = dInfo.createParam();
+	dp6.setName("-javadocnew");
+	dp6.setValue(".." + DIR_SEP + newapiname + DIR_SEP);
+	
+	if (getStats()) {
+	    // There are no arguments to this argument
+	    dInfo.createParam().setName("-stats");
+	    // We also have to copy two image files for the stats pages
+	    copyFile(jdiffHome + DIR_SEP + "black.gif",
+		     getDestdir().toString() + DIR_SEP + "black.gif");
+	    copyFile(jdiffHome + DIR_SEP + "background.gif",
+		     getDestdir().toString() + DIR_SEP + "background.gif");
+	}
+	
+	if (getDocchanges()) {
+	    // There are no arguments to this argument
+	    dInfo.createParam().setName("-docchanges");
+	}
+
+	// Execute the Javadoc command to compare the two XML files
+	jd.perform();
+    }
+
+    /**
+     * Generate the Javadoc for the project. If you want to generate
+     * the Javadoc report for the project with different parameters from the
+     * simple ones used here, then use the Javadoc Ant task directly, and 
+     * set the javadoc attribute to the "old" or "new" element.
+     *
+     * @param proj The current Project
+     */
+    protected void generateJavadoc(ProjectInfo proj) {	
+	String javadoc = proj.getJavadoc();
+	if (javadoc != null && javadoc.compareTo("generated") != 0) {
+	    project.log("Configured to use existing Javadoc located in " +  
+			javadoc, Project.MSG_INFO);
+	    return;
+	}
+
+	String apiname = proj.getName();
+	Javadoc jd = initJavadoc("Javadoc for " + apiname);
+	jd.setDestdir(new File(getDestdir().toString() + DIR_SEP + apiname));
+	addSourcePaths(jd, proj);
+
+	jd.setPrivate(true);
+	jd.setPackagenames(getPackageList(proj));
+
+	// Execute the Javadoc command to generate a regular Javadoc report
+	jd.perform();
+    }
+
+    /**
+     * Create a fresh new Javadoc task object and initialize it.
+     *
+     * @param logMsg String which appears as a prefix in the Ant log
+     * @return The new task.Javadoc object
+     */
+    protected Javadoc initJavadoc(String logMsg) {
+	Javadoc jd = new Javadoc();
+	jd.setProject(project); // Vital, otherwise Ant crashes
+	jd.setTaskName(logMsg);
+	jd.setSource(getSource()); // So we can set the language version
+	jd.init();
+
+	// Set up some common parameters for the Javadoc task
+	if (verboseAnt) {
+	    jd.setVerbose(true);
+	}
+	return jd;
+    }
+
+    /**
+     * Add the root directories for the given project to the Javadoc 
+     * sourcepath.
+     */
+    protected void addSourcePaths(Javadoc jd, ProjectInfo proj) {
+	Vector dirSets = proj.getDirsets();
+	int numDirSets = dirSets.size();
+	for (int i = 0; i < numDirSets; i++) {
+	    DirSet dirSet = (DirSet)dirSets.elementAt(i);
+	    jd.setSourcepath(new Path(project, dirSet.getDir(project).toString()));
+	}
+    }
+
+    /**
+     * Return the comma-separated list of packages. The list is
+     * generated from Ant DirSet tasks, and includes all directories
+     * in a hierarchy, e.g. com, com/acme. com/acme/foo. Duplicates are 
+     * ignored.
+     */
+    protected String getPackageList(ProjectInfo proj) throws BuildException {
+	String packageList = ""; 
+	java.lang.StringBuffer sb = new StringBuffer();
+	Vector dirSets = proj.getDirsets();
+	int numDirSets = dirSets.size();
+	boolean addComma = false;
+	for (int i = 0; i < numDirSets; i++) {
+	    DirSet dirSet = (DirSet)dirSets.elementAt(i);
+	    DirectoryScanner dirScanner = dirSet.getDirectoryScanner(project);
+	    String[] files = dirScanner.getIncludedDirectories();
+	    for (int j = 0; j < files.length; j++) {
+		if (!addComma){
+		    addComma = true;
+		} else {
+		    sb.append(",");
+		}
+		sb.append(files[j]);
+	    }
+	}
+	packageList = sb.toString();
+	if (packageList.compareTo("") == 0) {
+	    throw new BuildException("Error: no packages found to scan");
+	}
+	project.log(" Package list: " + packageList, Project.MSG_INFO);
+	
+	return packageList;
+    }
+
+    /**
+     * Copy a file from src to dst. Also checks that "destdir/changes" exists
+     */
+    protected void copyFile(String src, String dst){
+	File srcFile = new File(src);
+	File dstFile = new File(dst);
+	try {
+	    File reportSubdir = new File(getDestdir().toString() + 
+					 DIR_SEP + "changes");
+	    if (!reportSubdir.mkdir() && !reportSubdir.exists()) {
+		project.log("Warning: unable to create " + reportSubdir,
+			    Project.MSG_WARN);
+	    }
+
+	    InputStream in = new FileInputStream(src);
+	    OutputStream out = new FileOutputStream(dst);
+		
+	    // Transfer bytes from in to out
+	    byte[] buf = new byte[1024];
+	    int len;
+	    while ((len = in.read(buf)) > 0) {
+		out.write(buf, 0, len);
+	    }
+	    in.close();
+	    out.close();
+	} catch (java.io.FileNotFoundException fnfe) {
+	    project.log("Warning: unable to copy " + src.toString() + 
+			" to " + dst.toString(), Project.MSG_WARN);
+	    // Discard the exception
+	} catch (java.io.IOException ioe) {
+	    project.log("Warning: unable to copy " + src.toString() + 
+			" to " + dst.toString(), Project.MSG_WARN);
+	    // Discard the exception
+	}
+    }
+
+    /**
+     * The JDiff Ant task does not inherit from an Ant task, such as the 
+     * Javadoc task, though this is usually how most Tasks are
+     * written. This is because JDiff needs to run Javadoc three times
+     * (twice for generating XML, once for generating HTML). The
+     * Javadoc task has not easy way to reset its list of packages, so
+     * we needed to be able to crate new Javadoc task objects.
+     *
+     * Note: Don't confuse this class with the ProjectInfo used by JDiff. 
+     * This Project class is from Ant.
+     */
+    private Project project;
+
+    /**
+     * Used as part of Ant's startup.
+     */
+    public void setProject(Project proj) {
+        project = proj;
+    }
+
+    /** 
+     * Ferward or backward slash, as appropriate.
+     */
+    static String DIR_SEP = System.getProperty("file.separator");
+
+    /**
+     * JDIFF_HOME must be set as a property in the Ant build file.
+     * It should be set to the root JDiff directory, ie. the one where 
+     * jdiff.jar is found.
+     */
+    private String jdiffHome = "(not set)";
+
+    /**
+     * The classpath used by Javadoc to find jdiff.jar and xerces.jar.
+     */
+    private String jdiffClassPath = "(not set)";
+
+    /* ***************************************************************** */
+    /* * Objects and methods which are related to attributes           * */
+    /* ***************************************************************** */
+
+    /** 
+     * The destination directory for the generated report.
+     * The default is "./jdiff_report".
+     */
+    private File destdir = new File("jdiff_report");
+
+    /**
+     * Used to store the destdir attribute of the JDiff task XML element.
+     */
+    public void setDestdir(File value) {
+	this.destdir = value;
+    }
+
+    public File getDestdir() {
+	return this.destdir;
+    }
+
+    /** 
+     * Increases the JDiff Ant task logging verbosity if set with "yes", "on" 
+     * or true". Default has to be false.
+     * To increase verbosity of Javadoc, start Ant with -v or -verbose.
+     */ 
+    private boolean verbose = false;
+
+    public void setVerbose(boolean value) {
+	this.verbose = value;
+    }
+
+    public boolean getVerbose() {
+	return this.verbose;
+    }
+
+    /** 
+     * Set if ant was started with -v or -verbose 
+     */
+    private boolean verboseAnt = false;
+
+    /** 
+     * Add the -docchanges argument, to track changes in Javadoc documentation
+     * as well as changes in classes etc.
+     */ 
+    private boolean docchanges = false;
+
+    public void setDocchanges(boolean value) {
+	this.docchanges = value;
+    }
+
+    public boolean getDocchanges() {
+	return this.docchanges;
+    }
+
+    /** 
+     * Add statistics to the report if set. Default can only be false.
+     */ 
+    private boolean stats = false;
+
+    public void setStats(boolean value) {
+	this.stats = value;
+    }
+
+    public boolean getStats() {
+	return this.stats;
+    }
+
+    /**
+     * Allow the source language version to be specified.
+     */
+    private String source = "1.5"; // Default is 1.5, so generics will work
+    
+    public void setSource(String source) {
+        this.source = source;
+    }
+    
+    public String getSource() {
+        return source;
+    }
+
+    /* ***************************************************************** */
+    /* * Classes and objects which are related to elements             * */
+    /* ***************************************************************** */
+
+    /**
+     * A ProjectInfo-derived object for the older version of the project
+     */
+    private ProjectInfo oldProject = null;
+
+    /**
+     * Used to store the child element named "old", which is under the 
+     * JDiff task XML element.
+     */
+    public void addConfiguredOld(ProjectInfo projInfo) {
+	oldProject = projInfo;
+    }
+
+    /**
+     * A ProjectInfo-derived object for the newer version of the project
+     */
+    private ProjectInfo newProject = null;
+
+    /**
+     * Used to store the child element named "new", which is under the 
+     * JDiff task XML element.
+     */
+    public void addConfiguredNew(ProjectInfo projInfo) {
+	newProject = projInfo;
+    }
+
+    /**
+     * This class handles the information about a project, whether it is
+     * the older or newer version.
+     *
+     * Note: Don't confuse this class with the Project used by Ant.
+     * This ProjectInfo class is from local to this task.
+     */
+    public static class ProjectInfo {
+	/** 
+	 * The name of the project. This is used (without spaces) as the 
+	 * base of the name of the file which contains the XML representing 
+	 * the project.
+	 */
+	private String name;
+
+	public void setName(String value) {
+	    name = value;
+	}
+
+	public String getName() {
+	    return name;
+	}
+
+	/** 
+	 * The location of the Javadoc HTML for this project. Default value
+	 * is "generate", which will cause the Javadoc to be generated in 
+	 * a subdirectory named "name" in the task's destdir directory.
+	 */
+	private String javadoc;
+
+	public void setJavadoc(String value) {
+	    javadoc = value;
+	}
+
+	public String getJavadoc() {
+	    return javadoc;
+	}
+
+ 	/**
+	 * These are the directories which contain the packages which make 
+	 * up the project. Filesets are not supported by JDiff.
+	 */
+	private Vector dirsets = new Vector();
+
+	public void setDirset(DirSet value) {
+	    dirsets.add(value);
+	}
+
+	public Vector getDirsets() {
+	    return dirsets;
+	}
+
+	/** 
+	 * Used to store the child element named "dirset", which is under the 
+	 * "old" or "new" XML elements.
+	 */
+	public void addDirset(DirSet aDirset) {
+	    setDirset(aDirset);
+	}
+	
+    }
+}
diff --git a/src/jdiff/MemberDiff.java b/src/jdiff/MemberDiff.java
new file mode 100755
index 0000000..28e3258
--- /dev/null
+++ b/src/jdiff/MemberDiff.java
@@ -0,0 +1,73 @@
+package jdiff;
+
+import java.util.*;
+import com.sun.javadoc.*;
+
+/**
+ * The changes between two class constructor, method or field members.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+class MemberDiff {
+
+    /** The name of the member. */
+    public String name_;
+
+    /** 
+     * The old member type. For methods, this is the return type. 
+     */
+    public String oldType_ = null;
+    /** 
+     * The new member type. For methods, this is the return type.
+     */
+    public String newType_ = null;
+
+    /** The old signature. Null except for methods. */
+    public String oldSignature_ = null;
+    /** The new signature. Null except for methods. */
+    public String newSignature_ = null;
+    
+    /** 
+     * The old list of exceptions. Null except for methods and constructors. 
+     */
+    public String oldExceptions_ = null;
+    /** 
+     * The new list of exceptions. Null except for methods and constructors. 
+     */
+    public String newExceptions_ = null;
+    
+    /** 
+     * A string describing the changes in documentation. 
+     */
+    public String documentationChange_ = null;
+
+    /**
+     * A string describing the changes in modifiers.      
+     * Changes can be in whether this is abstract, static, final, and in 
+     * its visibility.
+     * Null if no change. 
+     */
+    public String modifiersChange_ = null;
+
+    /**
+     * The class name where the new member is defined.
+     * Null if no change in inheritance. 
+     */
+    public String inheritedFrom_ = null;
+
+    /** Default constructor. */
+    public MemberDiff(String name) {
+        name_ = name;
+    }   
+
+    /** Add a change in the modifiers. */
+    public void addModifiersChange(String commonModifierChanges) {
+        if (commonModifierChanges != null) {
+            if (modifiersChange_ == null)
+                modifiersChange_ = commonModifierChanges;
+            else
+                modifiersChange_ += " " + commonModifierChanges;
+        }
+    }
+}
diff --git a/src/jdiff/MergeChanges.java b/src/jdiff/MergeChanges.java
new file mode 100755
index 0000000..a8a4c85
--- /dev/null
+++ b/src/jdiff/MergeChanges.java
@@ -0,0 +1,342 @@
+package jdiff;
+
+import java.util.*;
+
+/**
+ * Convert some remove and add operations into change operations.
+ *
+ * Once the numbers of members removed and added are known
+ * we can deduce more information about changes. For instance, if there are
+ * two methods with the same name, and one or more of them has a 
+ * parameter type change, then this can only be reported as removing 
+ * the old version(s) and adding the new version(s), because there are 
+ * multiple methods with the same name. 
+ *
+ * However, if only <i>one</i> method with a given name is removed, and  
+ * only <i>one</i> method with the same name is added, we can convert these
+ * operations to a change operation. For constructors, this is true if 
+ * the types are the same. For fields, the field names have to be the same, 
+ * though this should never occur, since field names are unique.
+ *
+ * Another merge which can be made is if two or more methods with the same name
+ * were marked as removed and added because of changes other than signature.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+class MergeChanges {
+
+    /**
+     * Convert some remove and add operations into change operations.
+     *
+     * Note that if a single thread modifies a collection directly while it is 
+     * iterating over the collection with a fail-fast iterator, the iterator 
+     * will throw java.util.ConcurrentModificationException   
+     */
+    public static void mergeRemoveAdd(APIDiff apiDiff) {
+        // Go through all the ClassDiff objects searching for the above cases.
+        Iterator iter = apiDiff.packagesChanged.iterator();
+        while (iter.hasNext()) {
+            PackageDiff pkgDiff = (PackageDiff)(iter.next());
+            Iterator iter2 = pkgDiff.classesChanged.iterator();
+            while (iter2.hasNext()) {
+                ClassDiff classDiff = (ClassDiff)(iter2.next());
+                // Note: using iterators to step through the members gives a
+                // ConcurrentModificationException exception with large files.
+                // Constructors
+                ConstructorAPI[] ctorArr = new ConstructorAPI[classDiff.ctorsRemoved.size()];
+                ctorArr = (ConstructorAPI[])classDiff.ctorsRemoved.toArray(ctorArr);
+                for (int ctorIdx = 0; ctorIdx < ctorArr.length; ctorIdx++) {
+                    ConstructorAPI removedCtor = ctorArr[ctorIdx];
+                    mergeRemoveAddCtor(removedCtor, classDiff, pkgDiff);
+                }
+                // Methods
+                MethodAPI[] methodArr = new MethodAPI[classDiff.methodsRemoved.size()];
+                methodArr = (MethodAPI[])classDiff.methodsRemoved.toArray(methodArr);
+                for (int methodIdx = 0; methodIdx < methodArr.length; methodIdx++) {
+                    MethodAPI removedMethod = methodArr[methodIdx];
+                    // Only merge locally defined methods
+                    if (removedMethod.inheritedFrom_ == null)
+                        mergeRemoveAddMethod(removedMethod, classDiff, pkgDiff);
+                }
+                // Fields
+                FieldAPI[] fieldArr = new FieldAPI[classDiff.fieldsRemoved.size()];
+                fieldArr = (FieldAPI[])classDiff.fieldsRemoved.toArray(fieldArr);
+                for (int fieldIdx = 0; fieldIdx < fieldArr.length; fieldIdx++) {
+                    FieldAPI removedField = fieldArr[fieldIdx]; 
+                    // Only merge locally defined fields
+                    if (removedField.inheritedFrom_ == null)
+                        mergeRemoveAddField(removedField, classDiff, pkgDiff);
+                }
+            }
+        }        
+    }
+
+    /**
+     * Convert some removed and added constructors into changed constructors.
+     */
+    public static void mergeRemoveAddCtor(ConstructorAPI removedCtor, ClassDiff classDiff, PackageDiff pkgDiff) {
+        // Search on the type of the constructor
+        int startRemoved = classDiff.ctorsRemoved.indexOf(removedCtor);
+        int endRemoved = classDiff.ctorsRemoved.lastIndexOf(removedCtor);
+        int startAdded = classDiff.ctorsAdded.indexOf(removedCtor);
+        int endAdded = classDiff.ctorsAdded.lastIndexOf(removedCtor);
+        if (startRemoved != -1 && startRemoved == endRemoved && 
+            startAdded != -1 && startAdded == endAdded) {
+            // There is only one constructor with the type of the
+            // removedCtor in both the removed and added constructors.
+            ConstructorAPI addedCtor = (ConstructorAPI)(classDiff.ctorsAdded.get(startAdded));
+            // Create a MemberDiff for this change
+            MemberDiff ctorDiff = new MemberDiff(classDiff.name_);
+            ctorDiff.oldType_ = removedCtor.type_;
+            ctorDiff.newType_ = addedCtor.type_; // Should be the same as removedCtor.type
+            ctorDiff.oldExceptions_ = removedCtor.exceptions_;
+            ctorDiff.newExceptions_ = addedCtor.exceptions_;
+            ctorDiff.addModifiersChange(removedCtor.modifiers_.diff(addedCtor.modifiers_));
+            // Track changes in documentation
+            if (APIComparator.docChanged(removedCtor.doc_, addedCtor.doc_)) {
+                String type = ctorDiff.newType_;
+                if (type.compareTo("void") == 0)
+                    type = "";
+                String fqName = pkgDiff.name_ + "." + classDiff.name_;
+                String link1 = "<a href=\"" + fqName + HTMLReportGenerator.reportFileExt + "\" class=\"hiddenlink\">";
+                String link2 = "<a href=\"" + fqName + HTMLReportGenerator.reportFileExt + "#" + fqName + ".ctor_changed(" + type + ")\" class=\"hiddenlink\">";
+                String id = pkgDiff.name_ + "." + classDiff.name_ + ".ctor(" + HTMLReportGenerator.simpleName(type) + ")";
+                String title = link1 + "Class <b>" + classDiff.name_ + 
+                    "</b></a>, " + link2 + "constructor <b>" + classDiff.name_ + "(" + HTMLReportGenerator.simpleName(type) + ")</b></a>";
+                ctorDiff.documentationChange_ = Diff.saveDocDiffs(pkgDiff.name_, classDiff.name_, removedCtor.doc_, addedCtor.doc_, id, title);
+            }
+            classDiff.ctorsChanged.add(ctorDiff);
+            // Now remove the entries from the remove and add lists
+            classDiff.ctorsRemoved.remove(startRemoved);
+            classDiff.ctorsAdded.remove(startAdded);
+            if (trace && ctorDiff.modifiersChange_ != null)
+                System.out.println("Merged the removal and addition of constructor into one change: " + ctorDiff.modifiersChange_);
+        }
+    }
+
+    /**
+     * Convert some removed and added methods into changed methods.
+     */
+    public static void mergeRemoveAddMethod(MethodAPI removedMethod, 
+                                            ClassDiff classDiff, 
+                                            PackageDiff pkgDiff) {
+        mergeSingleMethods(removedMethod, classDiff, pkgDiff);
+        mergeMultipleMethods(removedMethod, classDiff, pkgDiff);
+    }
+
+    /**
+     * Convert single removed and added methods into a changed method.
+     */
+    public static void mergeSingleMethods(MethodAPI removedMethod, ClassDiff classDiff, PackageDiff pkgDiff) {
+        // Search on the name of the method
+        int startRemoved = classDiff.methodsRemoved.indexOf(removedMethod);
+        int endRemoved = classDiff.methodsRemoved.lastIndexOf(removedMethod);
+        int startAdded = classDiff.methodsAdded.indexOf(removedMethod);
+        int endAdded = classDiff.methodsAdded.lastIndexOf(removedMethod);
+        if (startRemoved != -1 && startRemoved == endRemoved && 
+            startAdded != -1 && startAdded == endAdded) {
+            // There is only one method with the name of the
+            // removedMethod in both the removed and added methods.
+            MethodAPI addedMethod = (MethodAPI)(classDiff.methodsAdded.get(startAdded));
+            if (addedMethod.inheritedFrom_ == null) {
+                // Create a MemberDiff for this change
+                MemberDiff methodDiff = new MemberDiff(removedMethod.name_);
+                methodDiff.oldType_ = removedMethod.returnType_;
+                methodDiff.newType_ = addedMethod.returnType_;
+                methodDiff.oldSignature_ = removedMethod.getSignature();
+                methodDiff.newSignature_ = addedMethod.getSignature();
+                methodDiff.oldExceptions_ = removedMethod.exceptions_;
+                methodDiff.newExceptions_ = addedMethod.exceptions_;
+                // The addModifiersChange field may not have been
+                // initialized yet if there were multiple methods of the same
+                // name.
+                diffMethods(methodDiff, removedMethod, addedMethod);
+                methodDiff.addModifiersChange(removedMethod.modifiers_.diff(addedMethod.modifiers_));
+                // Track changes in documentation
+                if (APIComparator.docChanged(removedMethod.doc_, addedMethod.doc_)) {
+                    String sig = methodDiff.newSignature_;
+                    if (sig.compareTo("void") == 0)
+                        sig = "";
+                    String fqName = pkgDiff.name_ + "." + classDiff.name_;
+                    String link1 = "<a href=\"" + fqName + HTMLReportGenerator.reportFileExt + "\" class=\"hiddenlink\">";
+                    String link2 = "<a href=\"" + fqName + HTMLReportGenerator.reportFileExt + "#" + fqName + "." + addedMethod.name_ + "_changed(" + sig + ")\" class=\"hiddenlink\">";
+                    String id = pkgDiff.name_ + "." + classDiff.name_ + ".dmethod." + addedMethod.name_ + "(" + HTMLReportGenerator.simpleName(sig) + ")";
+                    String title = link1 + "Class <b>" + classDiff.name_ + "</b></a>, " +
+                        link2 +  HTMLReportGenerator.simpleName(methodDiff.newType_) + " <b>" + addedMethod.name_ + "(" + HTMLReportGenerator.simpleName(sig) + ")</b></a>";
+                    methodDiff.documentationChange_ = Diff.saveDocDiffs(pkgDiff.name_, classDiff.name_, removedMethod.doc_, addedMethod.doc_, id, title);
+                }
+                classDiff.methodsChanged.add(methodDiff);
+                // Now remove the entries from the remove and add lists
+                classDiff.methodsRemoved.remove(startRemoved);
+                classDiff.methodsAdded.remove(startAdded);
+                if (trace) {
+                    System.out.println("Merged the removal and addition of method " + 
+                                       removedMethod.name_ + 
+                                       " into one change");
+                }
+            } //if (addedMethod.inheritedFrom_ == null)
+        }
+    }
+
+    /**
+     * Convert multiple removed and added methods into changed methods.
+     * This handles the case where the methods' signatures are unchanged, but
+     * something else changed.
+     */
+    public static void mergeMultipleMethods(MethodAPI removedMethod, ClassDiff classDiff, PackageDiff pkgDiff) {
+        // Search on the name and signature of the method
+        int startRemoved = classDiff.methodsRemoved.indexOf(removedMethod);
+        int endRemoved = classDiff.methodsRemoved.lastIndexOf(removedMethod);
+        int startAdded = classDiff.methodsAdded.indexOf(removedMethod);
+        int endAdded = classDiff.methodsAdded.lastIndexOf(removedMethod);
+        if (startRemoved != -1 && endRemoved != -1 && 
+            startAdded != -1 && endAdded != -1) {
+            // Find the index of the current removed method
+            int removedIdx = -1;
+            for (int i = startRemoved; i <= endRemoved; i++) {                
+                if (removedMethod.equalSignatures(classDiff.methodsRemoved.get(i))) {
+                    removedIdx = i;
+                    break;
+                }
+            }
+            if (removedIdx == -1) {
+                System.out.println("Error: removed method index not found");
+                System.exit(5);
+            }
+            // Find the index of the added method with the same signature, if 
+            // it exists, and make sure it is defined locally.
+            int addedIdx = -1;
+            for (int i = startAdded; i <= endAdded; i++) {
+                MethodAPI addedMethod2 = (MethodAPI)(classDiff.methodsAdded.get(i));
+                if (addedMethod2.inheritedFrom_ == null &&
+                    removedMethod.equalSignatures(addedMethod2))
+                    addedIdx = i;
+                    break;
+            }
+            if (addedIdx == -1)
+                return;
+            MethodAPI addedMethod = (MethodAPI)(classDiff.methodsAdded.get(addedIdx));
+            // Create a MemberDiff for this change
+            MemberDiff methodDiff = new MemberDiff(removedMethod.name_);
+            methodDiff.oldType_ = removedMethod.returnType_;
+            methodDiff.newType_ = addedMethod.returnType_;
+            methodDiff.oldSignature_ = removedMethod.getSignature();
+            methodDiff.newSignature_ = addedMethod.getSignature();
+            methodDiff.oldExceptions_ = removedMethod.exceptions_;
+            methodDiff.newExceptions_ = addedMethod.exceptions_;
+                // The addModifiersChange field may not have been
+                // initialized yet if there were multiple methods of the same
+                // name.
+                diffMethods(methodDiff, removedMethod, addedMethod);
+            methodDiff.addModifiersChange(removedMethod.modifiers_.diff(addedMethod.modifiers_));
+            // Track changes in documentation
+            if (APIComparator.docChanged(removedMethod.doc_, addedMethod.doc_)) {
+                String sig = methodDiff.newSignature_;
+                if (sig.compareTo("void") == 0)
+                    sig = "";
+                String fqName = pkgDiff.name_ + "." + classDiff.name_;
+                String link1 = "<a href=\"" + fqName + HTMLReportGenerator.reportFileExt + "\" class=\"hiddenlink\">";
+                String link2 = "<a href=\"" + fqName + HTMLReportGenerator.reportFileExt + "#" + fqName + "." + addedMethod.name_ + "_changed(" + sig + ")\" class=\"hiddenlink\">";
+                String id = pkgDiff.name_ + "." + classDiff.name_ + ".dmethod." + addedMethod.name_ + "(" + HTMLReportGenerator.simpleName(sig) + ")";
+                String title = link1 + "Class <b>" + classDiff.name_ + "</b></a>, " +
+                    link2 +  HTMLReportGenerator.simpleName(methodDiff.newType_) + " <b>" + addedMethod.name_ + "(" + HTMLReportGenerator.simpleName(sig) + ")</b></a>";
+                methodDiff.documentationChange_ = Diff.saveDocDiffs(pkgDiff.name_, classDiff.name_, removedMethod.doc_, addedMethod.doc_, id, title);
+            }
+            classDiff.methodsChanged.add(methodDiff);
+            // Now remove the entries from the remove and add lists
+            classDiff.methodsRemoved.remove(removedIdx);
+            classDiff.methodsAdded.remove(addedIdx);
+            if (trace) {
+                System.out.println("Merged the removal and addition of method " + 
+                                   removedMethod.name_ + 
+                                   " into one change. There were multiple methods of this name.");
+            }
+        }
+    }
+
+    /**
+     * Track changes in methods related to abstract, native, and 
+     * synchronized modifiers here.
+     */
+    public static void diffMethods(MemberDiff methodDiff, 
+                                   MethodAPI oldMethod, 
+                                   MethodAPI newMethod) {
+        // Abstract or not
+        if (oldMethod.isAbstract_ != newMethod.isAbstract_) {
+            String changeText = "";
+            if (oldMethod.isAbstract_)
+                changeText += "Changed from abstract to non-abstract.";
+            else
+                changeText += "Changed from non-abstract to abstract.";
+            methodDiff.addModifiersChange(changeText);
+        }
+        // Native or not
+        if (Diff.showAllChanges && 
+	    oldMethod.isNative_ != newMethod.isNative_) {
+            String changeText = "";
+            if (oldMethod.isNative_)
+                changeText += "Changed from native to non-native.";
+            else
+                changeText += "Changed from non-native to native.";
+            methodDiff.addModifiersChange(changeText);
+        }
+        // Synchronized or not
+        if (Diff.showAllChanges && 
+	    oldMethod.isSynchronized_ != newMethod.isSynchronized_) {
+            String changeText = "";
+            if (oldMethod.isSynchronized_)
+                changeText += "Changed from synchronized to non-synchronized.";
+            else
+                changeText += "Changed from non-synchronized to synchronized.";
+            methodDiff.addModifiersChange(changeText);
+        }
+    }
+
+    /**
+     * Convert some removed and added fields into changed fields.
+     */
+    public static void mergeRemoveAddField(FieldAPI removedField, ClassDiff classDiff, PackageDiff pkgDiff) {
+        // Search on the name of the field
+        int startRemoved = classDiff.fieldsRemoved.indexOf(removedField);
+        int endRemoved = classDiff.fieldsRemoved.lastIndexOf(removedField);
+        int startAdded = classDiff.fieldsAdded.indexOf(removedField);
+        int endAdded = classDiff.fieldsAdded.lastIndexOf(removedField);
+        if (startRemoved != -1 && startRemoved == endRemoved && 
+            startAdded != -1 && startAdded == endAdded) {
+            // There is only one field with the name of the
+            // removedField in both the removed and added fields.
+            FieldAPI addedField = (FieldAPI)(classDiff.fieldsAdded.get(startAdded));
+            if (addedField.inheritedFrom_ == null) {
+                // Create a MemberDiff for this change
+                MemberDiff fieldDiff = new MemberDiff(removedField.name_);
+                fieldDiff.oldType_ = removedField.type_;
+                fieldDiff.newType_ = addedField.type_;
+                fieldDiff.addModifiersChange(removedField.modifiers_.diff(addedField.modifiers_));
+                // Track changes in documentation
+                if (APIComparator.docChanged(removedField.doc_, addedField.doc_)) {
+                    String fqName = pkgDiff.name_ + "." + classDiff.name_;
+                    String link1 = "<a href=\"" + fqName + HTMLReportGenerator.reportFileExt + "\" class=\"hiddenlink\">";
+                    String link2 = "<a href=\"" + fqName + HTMLReportGenerator.reportFileExt + "#" + fqName + "." + addedField.name_ + "\" class=\"hiddenlink\">";
+                    String id = pkgDiff.name_ + "." + classDiff.name_ + ".field." + addedField.name_;
+                    String title = link1 + "Class <b>" + classDiff.name_ + "</b></a>, " +
+                        link2 + HTMLReportGenerator.simpleName(fieldDiff.newType_) + " <b>" + addedField.name_ + "</b></a>";
+                    fieldDiff.documentationChange_ = Diff.saveDocDiffs(pkgDiff.name_, classDiff.name_, removedField.doc_, addedField.doc_, id, title);
+                }
+                classDiff.fieldsChanged.add(fieldDiff);
+                // Now remove the entries from the remove and add lists
+                classDiff.fieldsRemoved.remove(startRemoved);
+                classDiff.fieldsAdded.remove(startAdded);
+                if (trace) {
+                    System.out.println("Merged the removal and addition of field " + 
+                                       removedField.name_ + 
+                                       " into one change");
+                }
+            } //if (addedField.inheritedFrom == null) 
+        }
+    }
+
+    /** Set to enable increased logging verbosity for debugging. */
+    private static boolean trace = false;
+
+}
diff --git a/src/jdiff/MethodAPI.java b/src/jdiff/MethodAPI.java
new file mode 100755
index 0000000..2afdc80
--- /dev/null
+++ b/src/jdiff/MethodAPI.java
@@ -0,0 +1,159 @@
+package jdiff;
+
+import java.io.*;
+import java.util.*;
+
+/** 
+ * Class to represent a method, analogous to MethodDoc in the 
+ * Javadoc doclet API. 
+ * 
+ * The method used for Collection comparison (compareTo) must make its
+ * comparison based upon everything that is known about this method.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+class MethodAPI implements Comparable {
+
+    /** Name of the method. */
+    public String name_ = null;
+
+    /** Return type of the method. */
+    public String returnType_ = null;
+
+    /** 
+     * The fully qualified name of the class or interface this method is
+     * inherited from. If this is null, then the method is defined locally
+     * in this class or interface.
+     */
+    public String inheritedFrom_ = null;
+
+    /** 
+     * The exceptions thrown by this method, being all the exception types
+     * separated by commas. "no exceptions" if no exceptions are thrown.
+     */
+    public String exceptions_ = "no exceptions";
+
+    /** Set if this method is abstract. */
+    public boolean isAbstract_ = false;
+
+    /** Set if this method is native. */
+    public boolean isNative_ = false;
+
+    /** Set if this method is synchronized. */
+    public boolean isSynchronized_ = false;
+
+    /** Modifiers for this class. */
+    public Modifiers modifiers_;
+
+    public List params_; // ParamAPI[]
+
+    /** The doc block, default is null. */
+    public String doc_ = null;
+
+    /** Constructor. */
+    public MethodAPI(String name, String returnType, boolean isAbstract, 
+                     boolean isNative, boolean isSynchronized,
+                     Modifiers modifiers) {
+        name_ = name;
+        returnType_ = returnType;
+        isAbstract_ = isAbstract;
+        isNative_ = isNative;
+        isSynchronized_ = isSynchronized;
+        modifiers_ = modifiers;
+        params_ = new ArrayList(); // ParamAPI[]
+    }
+
+    /** Copy constructor. */
+    public MethodAPI(MethodAPI m) {
+        name_ = m.name_;
+        returnType_ = m.returnType_;
+        inheritedFrom_ = m.inheritedFrom_;
+        exceptions_ = m.exceptions_;
+        isAbstract_ = m.isAbstract_;
+        isNative_ = m.isNative_;
+        isSynchronized_ = m.isSynchronized_;
+        modifiers_ = m.modifiers_; // Note: shallow copy
+        params_ = m.params_; // Note: shallow copy
+        doc_ = m.doc_;
+        signature_ = m.signature_; // Cached
+    }
+
+    /** 
+     * Compare two methods, including the return type, and parameter 
+     * names and types, and modifiers. 
+     */
+    public int compareTo(Object o) {
+        MethodAPI oMethod = (MethodAPI)o;
+        int comp = name_.compareTo(oMethod.name_);
+        if (comp != 0)
+            return comp;
+        comp = returnType_.compareTo(oMethod.returnType_);
+        if (comp != 0)
+            return comp;
+        if (APIComparator.changedInheritance(inheritedFrom_, oMethod.inheritedFrom_) != 0)
+            return -1;
+        if (isAbstract_ != oMethod.isAbstract_) {
+            return -1;
+        }
+        if (Diff.showAllChanges && 
+	    isNative_ != oMethod.isNative_) {
+            return -1;
+        }
+        if (Diff.showAllChanges && 
+	    isSynchronized_ != oMethod.isSynchronized_) {
+            return -1;
+        }
+        comp = exceptions_.compareTo(oMethod.exceptions_);
+        if (comp != 0)
+            return comp;
+        comp = modifiers_.compareTo(oMethod.modifiers_);
+        if (comp != 0)
+            return comp;
+        comp = getSignature().compareTo(oMethod.getSignature());
+        if (comp != 0)
+            return comp;
+        if (APIComparator.docChanged(doc_, oMethod.doc_))
+            return -1;
+        return 0;
+    }
+  
+    /** 
+     * Tests two methods, using just the method name, used by indexOf(). 
+     */
+    public boolean equals(Object o) {
+        if (name_.compareTo(((MethodAPI)o).name_) == 0)
+            return true;
+        return false;
+    }
+    
+    /** 
+     * Tests two methods for equality, using just the signature.
+     */
+    public boolean equalSignatures(Object o) {
+        if (getSignature().compareTo(((MethodAPI)o).getSignature()) == 0)
+            return true;
+        return false;
+    }
+    
+    /** Cached result of getSignature(). */
+    public String signature_ = null;
+
+    /** Return the signature of the method. */
+    public String getSignature() {
+        if (signature_ != null)
+            return signature_;
+        String res = "";
+        boolean first = true;
+        Iterator iter = params_.iterator();
+        while (iter.hasNext()) {
+            if (!first)
+                res += ", ";
+            ParamAPI param = (ParamAPI)(iter.next());
+            res += param.toString();
+            first = false;
+        }
+        signature_ = res;
+        return res; 
+    }
+}
diff --git a/src/jdiff/Modifiers.java b/src/jdiff/Modifiers.java
new file mode 100755
index 0000000..70f58e8
--- /dev/null
+++ b/src/jdiff/Modifiers.java
@@ -0,0 +1,105 @@
+package jdiff;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Track the various modifiers for a program element.
+ *
+ * The method used for Collection comparison (compareTo) must make its
+ * comparison based upon everything that is known about this set of modifiers.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+class Modifiers implements Comparable {
+
+    /** Set if the program element is static. */
+    public boolean isStatic = false;
+
+    /** Set if the program element is final. */
+    public boolean isFinal = false;
+
+    /** Set if the program element is deprecated. */
+    public boolean isDeprecated = false;
+
+    /** 
+     * The visibility level; "public", "protected", "package" or 
+     * "private" 
+     */
+    public String visibility = null;
+
+    /** Default constructor. */
+    public Modifiers() {
+    }
+
+    /** Compare two Modifiers objects by their contents. */
+    public int compareTo(Object o) {
+        Modifiers oModifiers = (Modifiers)o;
+        if (isStatic != oModifiers.isStatic)
+            return -1;
+        if (isFinal != oModifiers.isFinal)
+            return -1;
+        if (isDeprecated != oModifiers.isDeprecated)
+            return -1;
+        if (visibility != null) {
+            int comp = visibility.compareTo(oModifiers.visibility);
+            if (comp != 0)
+                return comp;
+        }
+        return 0;
+    }
+
+    /** 
+     * Generate a String describing the differences between the current
+     * (old) Modifiers object and a new Modifiers object. The string has 
+     * no leading space, but does end in a period.
+     *
+     * @param newModifiers The new Modifiers object.
+     * @return The description of the differences, null if there is no change.
+     */
+    public String diff(Modifiers newModifiers) {
+        String res = "";
+        boolean hasContent = false;
+        if (isStatic != newModifiers.isStatic) {
+            res += "Change from ";
+            if (isStatic) 
+                res += "static to non-static.<br>";
+            else
+                res += "non-static to static.<br>";
+            hasContent = true;
+        }
+        if (isFinal != newModifiers.isFinal) {
+            if (hasContent)
+                res += " ";
+            res += "Change from ";
+            if (isFinal) 
+                res += "final to non-final.<br>";
+            else
+                res += "non-final to final.<br>";
+            hasContent = true;
+        }
+        if (isDeprecated != newModifiers.isDeprecated) {
+            if (hasContent)
+                res += " ";
+            if (isDeprecated)
+                res += "Change from deprecated to undeprecated.<br>";
+            else
+                res += "<b>Now deprecated</b>.<br>";
+            hasContent = true;
+        }
+        if (visibility != null) {
+            int comp = visibility.compareTo(newModifiers.visibility);
+            if (comp != 0) {
+                if (hasContent)
+                    res += " ";
+                res += "Change of visibility from " + visibility + " to " + 
+                    newModifiers.visibility + ".<br>";
+                hasContent = true;
+            }
+        }
+        if (res.compareTo("") == 0)
+            return null;
+        return res;
+    }
+}
diff --git a/src/jdiff/Options.java b/src/jdiff/Options.java
new file mode 100755
index 0000000..748da7c
--- /dev/null
+++ b/src/jdiff/Options.java
@@ -0,0 +1,443 @@
+package jdiff;
+
+import java.io.*;
+import java.util.*;
+import com.sun.javadoc.*;
+
+/** 
+ * Class to handle options for JDiff.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+public class Options {
+
+    /** Default constructor. */
+    public Options() {
+    }
+
+    /**
+     * Returns the "length" of a given option. If an option takes no
+     * arguments, its length is one. If it takes one argument, its
+     * length is two, and so on. This method is called by Javadoc to
+     * parse the options it does not recognize. It then calls
+     * {@link #validOptions} to validate them.
+     * <blockquote>
+     * <b>Note:</b><br>
+     * The options arrive as case-sensitive strings. For options that
+     * are not case-sensitive, use toLowerCase() on the option string
+     * before comparing it.
+     * </blockquote>
+     *
+     * @param option  a String containing an option
+     * @return an int telling how many components that option has
+     */
+    public static int optionLength(String option) {
+        String opt = option.toLowerCase();
+        
+        // Standard options
+        if (opt.equals("-authorid"))  return 2;
+        if (opt.equals("-versionid")) return 2;
+        if (opt.equals("-d"))         return 2;
+        if (opt.equals("-classlist")) return 1;
+        if (opt.equals("-title"))     return 2;
+        if (opt.equals("-docletid"))  return 1;
+        if (opt.equals("-evident"))   return 2;
+        if (opt.equals("-skippkg"))   return 2;
+        if (opt.equals("-skipclass")) return 2;
+        if (opt.equals("-execdepth")) return 2;
+        if (opt.equals("-help"))      return 1;
+        if (opt.equals("-version"))      return 1;
+        if (opt.equals("-package"))   return 1;
+        if (opt.equals("-protected")) return 1;
+        if (opt.equals("-public"))    return 1;
+        if (opt.equals("-private"))   return 1;
+        if (opt.equals("-sourcepath")) return 2;
+        
+        // Options to control JDiff
+        if (opt.equals("-apiname"))    return 2;
+        if (opt.equals("-oldapi"))    return 2;
+        if (opt.equals("-newapi"))    return 2;
+
+        // Options to control the location of the XML files
+        if (opt.equals("-apidir"))       return 2;
+        if (opt.equals("-oldapidir"))    return 2;
+        if (opt.equals("-newapidir"))    return 2;
+        if (opt.equals("-usercommentsdir"))    return 2;
+
+
+        // Options for the exclusion level for classes and members
+        if (opt.equals("-excludeclass"))    return 2;
+        if (opt.equals("-excludemember"))    return 2;
+
+        if (opt.equals("-firstsentence"))    return 1;
+        if (opt.equals("-docchanges"))    return 1;
+        if (opt.equals("-packagesonly"))    return 1;
+        if (opt.equals("-showallchanges"))    return 1;
+
+        // Option to change the location for the existing Javadoc
+        // documentation for the new API. Default is "../"
+        if (opt.equals("-javadocnew"))    return 2;
+        // Option to change the location for the existing Javadoc
+        // documentation for the old API. Default is null.
+        if (opt.equals("-javadocold"))    return 2;
+
+        if (opt.equals("-baseuri"))    return 2;
+
+        // Option not to suggest comments at all
+        if (opt.equals("-nosuggest"))    return 2;
+
+        // Option to enable checking that the comments end with a period.
+        if (opt.equals("-checkcomments"))    return 1;
+        // Option to retain non-printing characters in comments.
+        if (opt.equals("-retainnonprinting"))    return 1;
+        // Option for the name of the exclude tag
+        if (opt.equals("-excludetag"))    return 2;
+        // Generate statistical output
+        if (opt.equals("-stats"))    return 1;
+
+        // Set the browser window title
+        if (opt.equals("-windowtitle"))    return 2;
+        // Set the report title
+        if (opt.equals("-doctitle"))    return 2;
+
+        return 0;
+    }//optionLength()
+
+   /**
+    * After parsing the available options using {@link #optionLength},
+    * Javadoc invokes this method with an array of options-arrays, where
+    * the first item in any array is the option, and subsequent items in
+    * that array are its arguments. So, if -print is an option that takes
+    * no arguments, and -copies is an option that takes 1 argument, then
+    * <pre>
+    *     -print -copies 3
+    * </pre>
+    * produces an array of arrays that looks like:
+    * <pre>
+    *      option[0][0] = -print
+    *      option[1][0] = -copies
+    *      option[1][1] = 3
+    * </pre>
+    * (By convention, command line switches start with a "-", but
+    * they don't have to.)
+    * <p>
+    * <b>Note:</b><br>
+    * Javadoc passes <i>all</i>parameters to this method, not just
+    * those that Javadoc doesn't recognize. The only way to
+    * identify unexpected arguments is therefore to check for every
+    * Javadoc parameter as well as doclet parameters.
+    *
+    * @param options   an array of String arrays, one per option
+    * @param reporter  a DocErrorReporter for generating error messages
+    * @return true if no errors were found, and all options are
+    *         valid
+    */
+    public static boolean validOptions(String[][] options,
+                                       DocErrorReporter reporter) {
+        final DocErrorReporter errOut = reporter;
+        
+        // A nice object-oriented way of handling errors. An instance of this
+        // class puts out an error message and keeps track of whether or not
+        // an error was found.
+        class ErrorHandler {
+            boolean noErrorsFound = true;
+            void msg(String msg) {
+                noErrorsFound = false;
+                errOut.printError(msg);
+            }
+        }
+        
+        ErrorHandler err = new ErrorHandler();
+        if (trace)
+            System.out.println("Command line arguments: "); 
+        for (int i = 0; i < options.length; i++) {
+            for (int j = 0; j < options[i].length; j++) {
+                Options.cmdOptions += " " + options[i][j];
+                if (trace)
+                    System.out.print(" " + options[i][j]); 
+            }            
+        }
+        if (trace)
+            System.out.println(); 
+
+        for (int i = 0; i < options.length; i++) {
+            if (options[i][0].toLowerCase().equals("-apiname")) {
+                if (options[i].length < 2) {
+                    err.msg("No version identifier specified after -apiname option.");
+                } else if (JDiff.compareAPIs) {
+                    err.msg("Use the -apiname option, or the -oldapi and -newapi options, but not both.");
+                } else { 
+                    String filename = options[i][1];
+                    RootDocToXML.apiIdentifier = filename;
+                    filename = filename.replace(' ', '_');
+                    RootDocToXML.outputFileName =  filename + ".xml";
+                    JDiff.writeXML = true;
+                    JDiff.compareAPIs = false;
+                }
+                continue;
+            }
+            if (options[i][0].toLowerCase().equals("-apidir")) {
+                if (options[i].length < 2) {
+                    err.msg("No directory specified after -apidir option.");
+                } else {
+		    RootDocToXML.outputDirectory = options[i][1];
+                }
+                continue;
+            }
+	    if (options[i][0].toLowerCase().equals("-oldapi")) {
+                if (options[i].length < 2) {
+                    err.msg("No version identifier specified after -oldapi option.");
+                } else if (JDiff.writeXML) {
+                    err.msg("Use the -apiname or -oldapi option, but not both.");
+                } else { 
+                    String filename = options[i][1];
+                    filename = filename.replace(' ', '_');
+                    JDiff.oldFileName =  filename + ".xml";
+                    JDiff.writeXML = false;
+                    JDiff.compareAPIs = true;
+                }
+                continue;
+            }
+            if (options[i][0].toLowerCase().equals("-oldapidir")) {
+                if (options[i].length < 2) {
+                    err.msg("No directory specified after -oldapidir option.");
+                } else { 
+                	JDiff.oldDirectory = options[i][1];
+                }
+                continue;
+            }
+            if (options[i][0].toLowerCase().equals("-newapi")) {
+                if (options[i].length < 2) {
+                    err.msg("No version identifier specified after -newapi option.");
+                } else if (JDiff.writeXML) {
+                    err.msg("Use the -apiname or -newapi option, but not both.");
+                } else { 
+                    String filename = options[i][1];
+                    filename = filename.replace(' ', '_');
+                    JDiff.newFileName =  filename + ".xml";
+                    JDiff.writeXML = false;
+                    JDiff.compareAPIs = true;
+                }
+                continue;
+            }
+            if (options[i][0].toLowerCase().equals("-newapidir")) {
+                if (options[i].length < 2) {
+                    err.msg("No directory specified after -newapidir option.");
+                } else { 
+                	JDiff.newDirectory = options[i][1];
+                }
+                continue;
+            }
+            if (options[i][0].toLowerCase().equals("-usercommentsdir")) {
+                if (options[i].length < 2) {
+                    err.msg("Android: No directory specified after -usercommentsdir option.");
+                } else { 
+                    HTMLReportGenerator.commentsDir = options[i][1];
+                }
+                continue;
+            }
+            if (options[i][0].toLowerCase().equals("-d")) {
+                if (options[i].length < 2) {
+                    err.msg("No directory specified after -d option.");
+                } else {
+                    HTMLReportGenerator.outputDir = options[i][1];
+                }
+                continue;
+            }
+            if (options[i][0].toLowerCase().equals("-javadocnew")) {
+                if (options[i].length < 2) {
+                    err.msg("No location specified after -javadocnew option.");
+                } else {
+                    HTMLReportGenerator.newDocPrefix = options[i][1];
+                }
+                continue;
+            }
+            if (options[i][0].toLowerCase().equals("-javadocold")) {
+                if (options[i].length < 2) {
+                    err.msg("No location specified after -javadocold option.");
+                } else {
+                    HTMLReportGenerator.oldDocPrefix = options[i][1];
+                }
+                continue;
+            }
+            if (options[i][0].toLowerCase().equals("-baseuri")) {
+                if (options[i].length < 2) {
+                    err.msg("No base location specified after -baseURI option.");
+                } else {
+                    RootDocToXML.baseURI = options[i][1];
+                }
+                continue;
+            }
+            if (options[i][0].toLowerCase().equals("-excludeclass")) {
+                if (options[i].length < 2) {
+                    err.msg("No level (public|protected|package|private) specified after -excludeclass option.");
+                } else { 
+                    String level = options[i][1];
+                    if (level.compareTo("public") != 0 &&
+                        level.compareTo("protected") != 0 &&
+                        level.compareTo("package") != 0 &&
+                        level.compareTo("private") != 0) {
+                        err.msg("Level specified after -excludeclass option must be one of (public|protected|package|private).");
+                    } else {
+                        RootDocToXML.classVisibilityLevel = level;
+                    }
+                }
+                continue;
+            }
+            if (options[i][0].toLowerCase().equals("-excludemember")) {
+                if (options[i].length < 2) {
+                    err.msg("No level (public|protected|package|private) specified after -excludemember option.");
+                } else { 
+                    String level = options[i][1];
+                    if (level.compareTo("public") != 0 &&
+                        level.compareTo("protected") != 0 &&
+                        level.compareTo("package") != 0 &&
+                        level.compareTo("private") != 0) {
+                        err.msg("Level specified after -excludemember option must be one of (public|protected|package|private).");
+                    } else {
+                        RootDocToXML.memberVisibilityLevel = level;
+                    }
+                }
+                continue;
+            }
+            if (options[i][0].toLowerCase().equals("-firstsentence")) {
+                RootDocToXML.saveAllDocs = false;
+                continue;
+            }
+            if (options[i][0].toLowerCase().equals("-docchanges")) {
+                HTMLReportGenerator.reportDocChanges = true;
+                Diff.noDocDiffs = false;
+                continue;
+            }
+            if (options[i][0].toLowerCase().equals("-packagesonly")) {
+                RootDocToXML.packagesOnly = true;
+                continue;
+            }
+            if (options[i][0].toLowerCase().equals("-showallchanges")) {
+                Diff.showAllChanges = true;
+                continue;
+            }
+            if (options[i][0].toLowerCase().equals("-nosuggest")) {
+                if (options[i].length < 2) {
+                    err.msg("No level (all|remove|add|change) specified after -nosuggest option.");
+                } else { 
+                    String level = options[i][1];
+                    if (level.compareTo("all") != 0 &&
+                        level.compareTo("remove") != 0 &&
+                        level.compareTo("add") != 0 &&
+                        level.compareTo("change") != 0) {
+                        err.msg("Level specified after -nosuggest option must be one of (all|remove|add|change).");
+                    } else {
+                        if (level.compareTo("removal") == 0)
+                            HTMLReportGenerator.noCommentsOnRemovals = true;
+                        else if (level.compareTo("add") == 0)
+                            HTMLReportGenerator.noCommentsOnAdditions = true;
+                        else if (level.compareTo("change") == 0)
+                            HTMLReportGenerator.noCommentsOnChanges = true;
+                        else if (level.compareTo("all") == 0) {
+                            HTMLReportGenerator.noCommentsOnRemovals = true;
+                            HTMLReportGenerator.noCommentsOnAdditions = true;
+                            HTMLReportGenerator.noCommentsOnChanges = true;
+                        }
+                    }
+                }
+                continue;
+            }
+            if (options[i][0].toLowerCase().equals("-checkcomments")) {
+                APIHandler.checkIsSentence = true;
+                continue;
+            }
+            if (options[i][0].toLowerCase().equals("-retainnonprinting")) {
+                RootDocToXML.stripNonPrintables = false;
+                continue;
+            }
+            if (options[i][0].toLowerCase().equals("-excludetag")) {
+                if (options[i].length < 2) {
+                    err.msg("No exclude tag specified after -excludetag option.");
+                } else { 
+                    RootDocToXML.excludeTag = options[i][1];
+                    RootDocToXML.excludeTag = RootDocToXML.excludeTag.trim();
+                    RootDocToXML.doExclude = true;
+                }
+                continue;
+            }
+            if (options[i][0].toLowerCase().equals("-stats")) {
+                HTMLReportGenerator.doStats = true;
+                continue;
+            }
+            if (options[i][0].toLowerCase().equals("-doctitle")) {
+                if (options[i].length < 2) {
+                    err.msg("No HTML text specified after -doctitle option.");
+                } else { 
+                    HTMLReportGenerator.docTitle = options[i][1];
+                }
+                continue;
+            }
+            if (options[i][0].toLowerCase().equals("-windowtitle")) {
+                if (options[i].length < 2) {
+                    err.msg("No text specified after -windowtitle option.");
+                } else { 
+                    HTMLReportGenerator.windowTitle = options[i][1];
+                }
+                continue;
+            }
+            if (options[i][0].toLowerCase().equals("-version")) {
+                System.out.println("JDiff version: " + JDiff.version);
+                System.exit(0);
+            }
+            if (options[i][0].toLowerCase().equals("-help")) {
+                usage();
+                System.exit(0);
+            }
+        }//for
+        if (!JDiff.writeXML && !JDiff.compareAPIs) {
+            err.msg("First use the -apiname option to generate an XML file for one API.");
+            err.msg("Then use the -apiname option again to generate another XML file for a different version of the API.");
+            err.msg("Finally use the -oldapi option and -newapi option to generate a report about how the APIs differ.");
+        }
+        return err.noErrorsFound;
+    }// validOptions()
+
+    /** Display the arguments for JDiff. */
+    public static void usage() {
+        System.err.println("JDiff version: " + JDiff.version);
+        System.err.println("");
+        System.err.println("Valid JDiff arguments:");
+        System.err.println("");
+        System.err.println("  -apiname <Name of a version>");
+        System.err.println("  -oldapi <Name of a version>");
+        System.err.println("  -newapi <Name of a version>");
+        
+        System.err.println("  Optional Arguments");
+        System.err.println();
+        System.err.println("  -d <directory> Destination directory for output HTML files");
+        System.err.println("  -oldapidir <directory> Location of the XML file for the old API");
+        System.err.println("  -newapidir <directory> Location of the XML file for the new API");
+        System.err.println("  -sourcepath <location of Java source files>");
+        System.err.println("  -javadocnew <location of existing Javadoc files for the new API>");
+        System.err.println("  -javadocold <location of existing Javadoc files for the old API>");
+        System.err.println("  -usercommentsdir <directory> Path to dir containing the user_comments* file(s)");
+        
+        System.err.println("  -baseURI <base> Use \"base\" as the base location of the various DTDs and Schemas used by JDiff");
+        System.err.println("  -excludeclass [public|protected|package|private] Exclude classes which are not public, protected etc");
+        System.err.println("  -excludemember [public|protected|package|private] Exclude members which are not public, protected etc");
+        
+        System.err.println("  -firstsentence Save only the first sentence of each comment block with the API.");
+        System.err.println("  -docchanges Report changes in Javadoc comments between the APIs");
+        System.err.println("  -nosuggest [all|remove|add|change] Do not add suggested comments to all, or the removed, added or chabged sections");
+        System.err.println("  -checkcomments Check that comments are sentences");
+        System.err.println("  -stripnonprinting Remove non-printable characters from comments.");
+        System.err.println("  -excludetag <tag> Define the Javadoc tag which implies exclusion");
+        System.err.println("  -stats Generate statistical output");
+        System.err.println("  -help       (generates this output)");
+        System.err.println("");
+        System.err.println("For more help, see jdiff.html");
+    }
+    
+    /** All the options passed on the command line. Logged to XML. */
+    public static String cmdOptions = "";
+
+    /** Set to enable increased logging verbosity for debugging. */
+    private static boolean trace = false;
+}
diff --git a/src/jdiff/PackageAPI.java b/src/jdiff/PackageAPI.java
new file mode 100755
index 0000000..885752f
--- /dev/null
+++ b/src/jdiff/PackageAPI.java
@@ -0,0 +1,49 @@
+package jdiff;
+
+import java.io.*;
+import java.util.*;
+
+/** 
+ * Class to represent a package, analogous to PackageDoc in the 
+ * Javadoc doclet API. 
+ *
+ * The method used for Collection comparison (compareTo) must make its
+ * comparison based upon everything that is known about this package.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+class PackageAPI implements Comparable {
+
+    /** Full qualified name of the package. */
+    public String name_;
+
+    /** Classes within this package. */
+    public List classes_;  // ClassAPI[]
+
+    /** The doc block, default is null. */
+    public String doc_ = null;
+
+    /** Constructor. */
+    public PackageAPI(String name) {
+        name_ = name;
+        classes_ = new ArrayList(); // ClassAPI[]
+    }
+
+    /** Compare two PackageAPI objects by name. */
+    public int compareTo(Object o) {
+        PackageAPI oPackageAPI = (PackageAPI)o;
+        if (APIComparator.docChanged(doc_, oPackageAPI.doc_))
+            return -1;
+        return name_.compareTo(oPackageAPI.name_);
+    }
+
+    /** 
+     * Tests two packages, using just the package name, used by indexOf().
+     */
+    public boolean equals(Object o) {
+        if (name_.compareTo(((PackageAPI)o).name_) == 0)
+            return true;
+        return false;
+    }
+}
diff --git a/src/jdiff/PackageDiff.java b/src/jdiff/PackageDiff.java
new file mode 100755
index 0000000..ba94f6e
--- /dev/null
+++ b/src/jdiff/PackageDiff.java
@@ -0,0 +1,38 @@
+package jdiff;
+
+import java.util.*;
+import com.sun.javadoc.*;
+
+/**
+ * Changes between two packages.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+class PackageDiff {
+
+    public String name_;
+
+    /** Classes added in the new API. */
+    public List classesAdded = null;
+    /** Classes removed in the new API. */
+    public List classesRemoved = null;
+    /** Classes changed in the new API. */
+    public List classesChanged = null;
+
+    /** 
+     * A string describing the changes in documentation. 
+     */
+    public String documentationChange_ = null;
+
+    /* The percentage difference for this package. */
+    public double pdiff = 0.0;
+
+    /** Default constructor. */
+    public PackageDiff(String name) {
+        name_ = name;
+        classesAdded = new ArrayList(); // ClassAPI[]
+        classesRemoved = new ArrayList(); // ClassAPI[]
+        classesChanged = new ArrayList(); // ClassDiff[]
+    }   
+}
diff --git a/src/jdiff/ParamAPI.java b/src/jdiff/ParamAPI.java
new file mode 100755
index 0000000..196a4b5
--- /dev/null
+++ b/src/jdiff/ParamAPI.java
@@ -0,0 +1,55 @@
+package jdiff;
+
+import java.io.*;
+import java.util.*;
+
+/** 
+ * Class to represent any (name, type) pair such as a parameter. 
+ * Analogous to ParamType in the Javadoc doclet API. 
+ *
+ * The method used for Collection comparison (compareTo) must make its
+ * comparison based upon everything that is known about this parameter.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+class ParamAPI implements Comparable {
+    /** Name of the (name, type) pair. */
+    public String name_;
+
+    /** Type of the (name, type) pair. */
+    public String type_;
+
+    public ParamAPI(String name, String type) {
+        name_ = name;
+        type_ = type;
+    }
+
+    /** Compare two ParamAPI objects using both name and type. */
+    public int compareTo(Object o) {
+        ParamAPI oParamAPI = (ParamAPI)o;
+        int comp = name_.compareTo(oParamAPI.name_);
+        if (comp != 0)
+            return comp;
+        comp = type_.compareTo(oParamAPI.type_);
+        if (comp != 0)
+            return comp;
+        return 0;
+    }
+  
+    /** 
+     * Tests two ParamAPI objects using just the name, used by indexOf().
+     */
+    public boolean equals(Object o) {
+        if (name_.compareTo(((ParamAPI)o).name_) == 0)
+            return true;
+        return false;
+    }
+    
+    /** Used to create signatures. */
+    public String toString() {
+        if (type_.compareTo("void") == 0)
+            return "";
+        return type_;
+    }
+}  
diff --git a/src/jdiff/RootDocToXML.java b/src/jdiff/RootDocToXML.java
new file mode 100755
index 0000000..f68a60b
--- /dev/null
+++ b/src/jdiff/RootDocToXML.java
@@ -0,0 +1,1147 @@
+package jdiff;
+
+import com.sun.javadoc.*;
+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
diff --git a/src/jdiff/SingleComment.java b/src/jdiff/SingleComment.java
new file mode 100755
index 0000000..387dac9
--- /dev/null
+++ b/src/jdiff/SingleComment.java
@@ -0,0 +1,34 @@
+package jdiff;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Represents a single comment element. Has an identifier and some text.
+ * 
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+class SingleComment implements Comparable {
+
+    /** The identifier for this comment. */
+    public String id_ = null;
+
+    /** The text of this comment. */
+    public String text_ = null;
+
+    /** If false, then this comment is inactive. */
+    public boolean isUsed_ = true;
+
+    public SingleComment(String id, String text) {
+        // Escape the commentID in case it contains "<" or ">"
+        // characters (generics)
+        id_ = id.replaceAll("<", "&lt;").replaceAll(">", "&gt;");;
+        text_ = text;
+    }
+
+    /** Compare two SingleComment objects using just the id. */
+    public int compareTo(Object o) {
+        return id_.compareTo(((SingleComment)o).id_);
+    }
+}
diff --git a/src/jdiff/StreamReader.java b/src/jdiff/StreamReader.java
new file mode 100755
index 0000000..124fe85
--- /dev/null
+++ b/src/jdiff/StreamReader.java
@@ -0,0 +1,36 @@
+package jdiff;
+
+import java.util.*;
+import java.io.*;
+
+/**
+ * Reads in lines from an input stream and displays them.
+ *
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com.
+ */
+class StreamReader extends Thread {
+    /** The input stream. */
+    InputStream is_;
+        
+    /** Constructor which takes an InputStream. */
+    StreamReader(InputStream is) {
+        is_ = is;
+    }
+        
+    /** Method which is called when this thread is started. */
+    public void run() {
+        try {
+            InputStreamReader isr = new InputStreamReader(is_);
+            BufferedReader br = new BufferedReader(isr);
+            String line = null;
+            while((line = br.readLine()) != null)
+                System.out.println(line);    
+        } catch (IOException ioe) {
+            System.out.println("IO Error invoking Javadoc");
+            ioe.printStackTrace();  
+        } catch (Exception e) {
+            // Ignore read errors which indicate that the process is complete
+        }
+    }
+}
diff --git a/src/jdiff/XMLToAPI.java b/src/jdiff/XMLToAPI.java
new file mode 100755
index 0000000..8937a66
--- /dev/null
+++ b/src/jdiff/XMLToAPI.java
@@ -0,0 +1,377 @@
+package jdiff;
+
+import java.io.*;
+import java.util.*;
+
+/* For SAX parsing in APIHandler */
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.InputSource;
+import org.xml.sax.helpers.*;
+
+/**
+ * Creates an API object from an XML file. The API object is the internal 
+ * representation of an API.
+ * All methods in this class for populating an API object are static.
+ * 
+ * See the file LICENSE.txt for copyright details.
+ * @author Matthew Doar, mdoar@pobox.com
+ */
+public class XMLToAPI {
+
+    /** The instance of the API object which is populated from the file. */ 
+    private static API api_ = null;
+
+    /** Default constructor. */
+    private XMLToAPI() {
+    }   
+  
+    /** 
+     * Read the file where the XML representing the API is stored.
+     *
+     * @param filename The full name of the file containing the XML 
+     *                 representing the API
+     * @param createGlobalComments If set, then store possible comments
+     * @param apiName The simple name of the API file. If -oldapidir and 
+     *                -newapidir are not used, then this is the same as 
+     *                the filename parameter
+     */
+    public static API readFile(String filename, boolean createGlobalComments,
+			       String apiName) {
+        // The instance of the API object which is populated from the file. 
+        api_ = new API();
+        api_.name_ = apiName; // Checked later
+        try {
+            XMLReader parser = null;
+            DefaultHandler handler = new APIHandler(api_, createGlobalComments);
+            try {
+                String parserName = System.getProperty("org.xml.sax.driver");
+                if (parserName == null) {
+                    parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
+                } else {
+                    // Let the underlying mechanisms try to work out which 
+                    // class to instantiate
+                    parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader();
+                }
+            } catch (SAXException saxe) {
+                System.out.println("SAXException: " + saxe);
+                saxe.printStackTrace();
+                System.exit(1);
+            }
+            if (validateXML) {
+                parser.setFeature("http://xml.org/sax/features/namespaces", true);
+                parser.setFeature("http://xml.org/sax/features/validation", true);
+                parser.setFeature("http://apache.org/xml/features/validation/schema", true);
+            }
+
+            parser.setContentHandler(handler);
+            parser.setErrorHandler(handler);
+            parser.parse(new InputSource(new FileInputStream(new File(filename))));
+        } catch(org.xml.sax.SAXNotRecognizedException snre) {
+            System.out.println("SAX Parser does not recognize feature: " + snre);
+            snre.printStackTrace();
+            System.exit(1);
+        } catch(org.xml.sax.SAXNotSupportedException snse) {
+            System.out.println("SAX Parser feature is not supported: " + snse);
+            snse.printStackTrace();
+            System.exit(1);
+        } catch(org.xml.sax.SAXException saxe) {
+            System.out.println("SAX Exception parsing file '" + filename + "' : " + saxe);
+            saxe.printStackTrace();
+            System.exit(1);
+        } catch(java.io.IOException ioe) {
+            System.out.println("IOException parsing file '" + filename + "' : " + ioe);
+            ioe.printStackTrace();
+            System.exit(1);
+        }
+
+        // Add the inherited methods and fields to each class
+        addInheritedElements();
+        return api_;
+    } //readFile()
+
+    /** 
+     * Add the inherited methods and fields to each class in turn.
+     */
+    public static void addInheritedElements() {
+        Iterator iter = api_.packages_.iterator();
+        while (iter.hasNext()) {
+            PackageAPI pkg = (PackageAPI)(iter.next());
+            Iterator iter2 = pkg.classes_.iterator();
+            while (iter2.hasNext()) {
+                ClassAPI cls = (ClassAPI)(iter2.next());
+                // Look up any inherited classes or interfaces
+                if (cls.extends_ != null) {
+                    ClassAPI parent = (ClassAPI)api_.classes_.get(cls.extends_);
+                    if (parent != null)
+                        addInheritedElements(cls, parent, cls.extends_);
+                }
+                if (cls.implements_.size() != 0) {
+                    Iterator iter3 = cls.implements_.iterator();
+                    while (iter3.hasNext()) {
+                        String implName = (String)(iter3.next());
+                        ClassAPI parent = (ClassAPI)api_.classes_.get(implName);
+                        if (parent != null)
+                            addInheritedElements(cls, parent, implName);
+                    }
+                }
+            } //while (iter2.hasNext())
+        } //while (iter.hasNext())
+    }
+
+    /** 
+     * Add all the inherited methods and fields in the second class to 
+     * the first class, marking them as inherited from the second class.
+     * Do not add a method or a field if it is already defined locally.
+     *
+     * Only elements at the specified visibility level or
+     * higher appear in the XML file. All that remains to be tested for
+     * a private element, which is never inherited.
+     *
+     * If the parent class inherits any classes or interfaces, call this
+     * method recursively with those parents.
+     */
+    public static void addInheritedElements(ClassAPI child, ClassAPI parent,
+                                            String fqParentName) {
+        if (parent.methods_.size() != 0) {
+            Iterator iter = parent.methods_.iterator();
+            while (iter.hasNext()) {
+                MethodAPI m = (MethodAPI)(iter.next());
+                // See if it the method is overridden locally
+                boolean overridden = false;
+                Iterator iter2 = child.methods_.iterator();
+                while (iter2.hasNext()) {
+                    MethodAPI localM = (MethodAPI)(iter2.next());
+                    if (localM.name_.compareTo(m.name_) == 0 && 
+                        localM.getSignature().compareTo(m.getSignature()) == 0)
+                        overridden = true;
+                }
+                if (!overridden && m.inheritedFrom_ == null &&
+                    m.modifiers_.visibility != null && 
+                    m.modifiers_.visibility.compareTo("private") != 0) {
+                    MethodAPI m2 = new MethodAPI(m);
+                    m2.inheritedFrom_ = fqParentName;
+                    child.methods_.add(m2);
+                }
+            }            
+        }
+        if (parent.fields_.size() != 0) {
+            Iterator iter = parent.fields_.iterator();
+            while (iter.hasNext()) {
+                FieldAPI f = (FieldAPI)(iter.next());
+                if (child.fields_.indexOf(f) == -1 &&
+                    f.inheritedFrom_ == null &&
+                    f.modifiers_.visibility != null && 
+                    f.modifiers_.visibility.compareTo("private") != 0) {
+                    FieldAPI f2 = new FieldAPI(f);
+                    f2.inheritedFrom_ = fqParentName;
+                    child.fields_.add(f2);
+                }
+            }            
+        }
+
+        // Look up any inherited classes or interfaces
+        if (parent.extends_ != null) {
+            ClassAPI parent2 = (ClassAPI)api_.classes_.get(parent.extends_);
+            if (parent2 != null)
+                addInheritedElements(child, parent2, parent.extends_);
+        }
+        if (parent.implements_.size() != 0) {
+            Iterator iter3 = parent.implements_.iterator();
+            while (iter3.hasNext()) {
+                String implName = (String)(iter3.next());
+                ClassAPI parent2 = (ClassAPI)api_.classes_.get(implName);
+                if (parent2 != null)
+                    addInheritedElements(child, parent2, implName);
+            }
+        }
+    }
+
+//
+// Methods to add data to an API object. Called by the XML parser.
+//
+
+    /** 
+     * Set the name of the API object.
+     *
+     * @param name The name of the package.
+     */
+    public static void nameAPI(String name) {
+        if (name == null) {
+            System.out.println("Error: no API identifier found in the XML file '" + api_.name_ + "'");
+            System.exit(3);
+        }
+        // Check the given name against the filename currently stored in 
+        // the name_ field
+        String filename2 = name.replace(' ','_');
+        filename2 += ".xml";
+        if (filename2.compareTo(api_.name_) != 0) {
+            System.out.println("Warning: API identifier in the XML file (" + 
+                               name + ") differs from the name of the file '" +
+                               api_.name_ + "'");
+        }
+        api_.name_ = name;
+    }
+   
+    /** 
+     * Create a new package and add it to the API. Called by the XML parser. 
+     *
+     * @param name The name of the package.
+     */
+    public static void addPackage(String name) {
+        api_.currPkg_ = new PackageAPI(name);
+        api_.packages_.add(api_.currPkg_);
+    }
+   
+    /** 
+     * Create a new class and add it to the current package. Called by the XML parser. 
+     *
+     * @param name The name of the class.
+     * @param parent The name of the parent class, null if no class is extended.
+     * @param modifiers Modifiers for this class.
+     */
+    public static void addClass(String name, String parent, 
+                                boolean isAbstract,
+                                Modifiers modifiers) {
+        api_.currClass_ = new ClassAPI(name, parent, false, isAbstract, modifiers);
+        api_.currPkg_.classes_.add(api_.currClass_);
+        String fqName = api_.currPkg_.name_ + "." + name;
+        ClassAPI caOld = (ClassAPI)api_.classes_.put(fqName, api_.currClass_);
+        if (caOld != null) {
+            System.out.println("Warning: duplicate class : " + fqName + " found. Using the first instance only.");
+        }
+    }
+  
+    /** 
+     * Add an new interface and add it to the current package. Called by the 
+     * XML parser.
+     *
+     * @param name The name of the interface.
+     * @param parent The name of the parent interface, null if no 
+     *               interface is extended.
+     */
+    public static void addInterface(String name, String parent, 
+                                    boolean isAbstract,
+                                    Modifiers modifiers) {
+        api_.currClass_ = new ClassAPI(name, parent, true, isAbstract, modifiers);
+        api_.currPkg_.classes_.add(api_.currClass_);
+    }
+  
+    /** 
+     * Add an inherited interface to the current class. Called by the XML 
+     * parser.
+     *
+     * @param name The name of the inherited interface.
+     */
+    public static void addImplements(String name) {
+       api_.currClass_.implements_.add(name);
+    }
+  
+    /** 
+     * Add a constructor to the current class. Called by the XML parser.
+     *
+     * @param name The name of the constructor.
+     * @param type The type of the constructor.
+     * @param modifiers Modifiers for this constructor.
+     */
+    public static void addCtor(String type, Modifiers modifiers) {
+        String t = type;
+        if (t == null)
+            t = "void";
+        api_.currCtor_ = new ConstructorAPI(t, modifiers);
+        api_.currClass_.ctors_.add(api_.currCtor_);
+    }
+
+    /** 
+     * Add a method to the current class. Called by the XML parser.
+     *
+     * @param name The name of the method.
+     * @param returnType The return type of the method, null if it is void.
+     * @param modifiers Modifiers for this method.
+     */
+    public static void addMethod(String name, String returnType, 
+                                 boolean isAbstract, boolean isNative, 
+                                 boolean isSynchronized, Modifiers modifiers) {
+        String rt = returnType;
+        if (rt == null)
+            rt = "void";
+        api_.currMethod_ = new MethodAPI(name, rt, isAbstract, isNative,
+                                         isSynchronized, modifiers);
+        api_.currClass_.methods_.add(api_.currMethod_);
+    }
+
+    /** 
+     * Add a field to the current class. Called by the XML parser.
+     *
+     * @param name The name of the field.
+     * @param type The type of the field, null if it is void.
+     * @param modifiers Modifiers for this field.
+     */
+    public static void addField(String name, String type, boolean isTransient,
+                                boolean isVolatile, String value, Modifiers modifiers) {
+        String t = type;
+        if (t == null)
+            t = "void";
+        api_.currField_ = new FieldAPI(name, t, isTransient, isVolatile, value, modifiers);
+        api_.currClass_.fields_.add(api_.currField_);
+    }
+
+    /** 
+     * Add a parameter to the current method. Called by the XML parser.
+     * Constuctors have their type (signature) in an attribute, since it 
+     * is often shorter and makes parsing a little easier.
+     *
+     * @param name The name of the parameter.
+     * @param type The type of the parameter, null if it is void.
+     */
+    public static void addParam(String name, String type) {
+        String t = type;
+        if (t == null)
+            t = "void";
+        ParamAPI paramAPI = new ParamAPI(name, t);
+        api_.currMethod_.params_.add(paramAPI);
+    }
+
+    /** 
+     * Add an exception to the current method or constructor. 
+     * Called by the XML parser.
+     *
+     * @param name The name of the parameter.
+     * @param type The type of the parameter. 
+     *             May be null in JDiff1.0.8 and earlier versions.
+     * @param currElement Name of the current element.
+     */
+    public static void addException(String name, String type, String currElement) {
+	String exceptionId = type;
+	if (type == null || !showExceptionTypes)
+	    exceptionId = name;
+        if (currElement.compareTo("method") == 0) {
+            if (api_.currMethod_.exceptions_.compareTo("no exceptions") == 0)
+                api_.currMethod_.exceptions_ = exceptionId;
+            else
+                api_.currMethod_.exceptions_ += ", " + exceptionId;
+        } else {
+            if (api_.currCtor_.exceptions_.compareTo("no exceptions") == 0)
+                api_.currCtor_.exceptions_ = exceptionId;
+            else
+                api_.currCtor_.exceptions_ += ", " + exceptionId;
+        }
+    }
+
+    /** 
+     * If set, validate the XML which represents an API. By default, this is 
+     * not set for reasons of efficiency, and also because if JDiff generated 
+     * the XML, it should not need validating. 
+     */
+    public static boolean validateXML = false;
+
+    /** 
+     * If set, then store and display the whole qualified name of exceptions.
+     * If not set, then store and display just the name of the exception, 
+     * which is shorter, but may not detect when an exception changes class,
+     * but retains the same name.
+     */
+    private static boolean showExceptionTypes = true;
+}  
diff --git a/xerces.jar b/xerces.jar
new file mode 100644
index 0000000..8f762e1
--- /dev/null
+++ b/xerces.jar
Binary files differ
