diff --git a/Android.mk b/Android.mk
deleted file mode 100644
index 16f62cc..0000000
--- a/Android.mk
+++ /dev/null
@@ -1,11 +0,0 @@
-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
deleted file mode 100644
index e69de29..0000000
--- a/MODULE_LICENSE_LGPL
+++ /dev/null
diff --git a/NOTICE.txt b/NOTICE.txt
deleted file mode 100644
index fab48ed..0000000
--- a/NOTICE.txt
+++ /dev/null
@@ -1,506 +0,0 @@
-		  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
deleted file mode 100755
index 9f7529e..0000000
--- a/README.txt
+++ /dev/null
@@ -1,59 +0,0 @@
-
-                           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
deleted file mode 100755
index 3dd9657..0000000
--- a/build.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?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
deleted file mode 100755
index bb2368f..0000000
--- a/src/api.xsd
+++ /dev/null
@@ -1,111 +0,0 @@
-<?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
deleted file mode 100755
index cfee740..0000000
--- a/src/comments.xsd
+++ /dev/null
@@ -1,31 +0,0 @@
-<?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
deleted file mode 100755
index 2e8f117..0000000
--- a/src/jdiff/API.java
+++ /dev/null
@@ -1,429 +0,0 @@
-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
deleted file mode 100755
index b0f42ed..0000000
--- a/src/jdiff/APIComparator.java
+++ /dev/null
@@ -1,934 +0,0 @@
-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
deleted file mode 100755
index 4b4fd26..0000000
--- a/src/jdiff/APIDiff.java
+++ /dev/null
@@ -1,40 +0,0 @@
-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
deleted file mode 100755
index be1a6fc..0000000
--- a/src/jdiff/APIHandler.java
+++ /dev/null
@@ -1,362 +0,0 @@
-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
deleted file mode 100755
index 9490cc7..0000000
--- a/src/jdiff/ClassAPI.java
+++ /dev/null
@@ -1,91 +0,0 @@
-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
deleted file mode 100755
index 8742ab1..0000000
--- a/src/jdiff/ClassDiff.java
+++ /dev/null
@@ -1,154 +0,0 @@
-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
deleted file mode 100755
index 066e4f0..0000000
--- a/src/jdiff/Comments.java
+++ /dev/null
@@ -1,551 +0,0 @@
-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
deleted file mode 100755
index 8061fbe..0000000
--- a/src/jdiff/CommentsHandler.java
+++ /dev/null
@@ -1,210 +0,0 @@
-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
deleted file mode 100755
index bd0bf95..0000000
--- a/src/jdiff/CompareClassPdiffs.java
+++ /dev/null
@@ -1,25 +0,0 @@
-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
deleted file mode 100755
index 187e7bf..0000000
--- a/src/jdiff/ComparePkgPdiffs.java
+++ /dev/null
@@ -1,25 +0,0 @@
-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
deleted file mode 100755
index 7390a4d..0000000
--- a/src/jdiff/ConstructorAPI.java
+++ /dev/null
@@ -1,66 +0,0 @@
-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
deleted file mode 100755
index a9c9776..0000000
--- a/src/jdiff/Diff.java
+++ /dev/null
@@ -1,654 +0,0 @@
-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
deleted file mode 100755
index 2e4683a..0000000
--- a/src/jdiff/DiffMyers.java
+++ /dev/null
@@ -1,850 +0,0 @@
-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
deleted file mode 100755
index 9b2c13c..0000000
--- a/src/jdiff/DiffOutput.java
+++ /dev/null
@@ -1,54 +0,0 @@
-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
deleted file mode 100755
index 151e729..0000000
--- a/src/jdiff/FieldAPI.java
+++ /dev/null
@@ -1,107 +0,0 @@
-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
deleted file mode 100755
index a141e6c..0000000
--- a/src/jdiff/HTMLFiles.java
+++ /dev/null
@@ -1,368 +0,0 @@
-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
deleted file mode 100755
index d39e023..0000000
--- a/src/jdiff/HTMLIndexes.java
+++ /dev/null
@@ -1,1097 +0,0 @@
-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
deleted file mode 100755
index f6cf861..0000000
--- a/src/jdiff/HTMLReportGenerator.java
+++ /dev/null
@@ -1,2163 +0,0 @@
-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
deleted file mode 100755
index 6dada5c..0000000
--- a/src/jdiff/HTMLStatistics.java
+++ /dev/null
@@ -1,491 +0,0 @@
-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
deleted file mode 100755
index 14a7a97..0000000
--- a/src/jdiff/JDiff.java
+++ /dev/null
@@ -1,297 +0,0 @@
-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
deleted file mode 100755
index e5b14ac..0000000
--- a/src/jdiff/JDiffAntTask.java
+++ /dev/null
@@ -1,536 +0,0 @@
-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
deleted file mode 100755
index 28e3258..0000000
--- a/src/jdiff/MemberDiff.java
+++ /dev/null
@@ -1,73 +0,0 @@
-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
deleted file mode 100755
index a8a4c85..0000000
--- a/src/jdiff/MergeChanges.java
+++ /dev/null
@@ -1,342 +0,0 @@
-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
deleted file mode 100755
index 2afdc80..0000000
--- a/src/jdiff/MethodAPI.java
+++ /dev/null
@@ -1,159 +0,0 @@
-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
deleted file mode 100755
index 70f58e8..0000000
--- a/src/jdiff/Modifiers.java
+++ /dev/null
@@ -1,105 +0,0 @@
-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
deleted file mode 100755
index 748da7c..0000000
--- a/src/jdiff/Options.java
+++ /dev/null
@@ -1,443 +0,0 @@
-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
deleted file mode 100755
index 885752f..0000000
--- a/src/jdiff/PackageAPI.java
+++ /dev/null
@@ -1,49 +0,0 @@
-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
deleted file mode 100755
index ba94f6e..0000000
--- a/src/jdiff/PackageDiff.java
+++ /dev/null
@@ -1,38 +0,0 @@
-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
deleted file mode 100755
index 196a4b5..0000000
--- a/src/jdiff/ParamAPI.java
+++ /dev/null
@@ -1,55 +0,0 @@
-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
deleted file mode 100755
index f68a60b..0000000
--- a/src/jdiff/RootDocToXML.java
+++ /dev/null
@@ -1,1147 +0,0 @@
-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
deleted file mode 100755
index 387dac9..0000000
--- a/src/jdiff/SingleComment.java
+++ /dev/null
@@ -1,34 +0,0 @@
-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
deleted file mode 100755
index 124fe85..0000000
--- a/src/jdiff/StreamReader.java
+++ /dev/null
@@ -1,36 +0,0 @@
-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
deleted file mode 100755
index 8937a66..0000000
--- a/src/jdiff/XMLToAPI.java
+++ /dev/null
@@ -1,377 +0,0 @@
-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
deleted file mode 100644
index 8f762e1..0000000
--- a/xerces.jar
+++ /dev/null
Binary files differ
